[libdap] 01/13: upstream 3.14.0

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


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

mckinstry pushed a commit to tag unstable/3.14.0-2
in repository libdap.

commit 78e6bf536deb1175d30a827d5731de5c9883b1d9
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Sat May 2 09:46:21 2015 +0100

    upstream 3.14.0
---
 AlarmHandler.h                                     |     8 +-
 Array.cc                                           |   396 +-
 Array.h                                            |    90 +-
 AttrTable.cc                                       |    48 +-
 AttrTable.h                                        |    12 +-
 BaseType.cc                                        |   485 +-
 BaseType.h                                         |   218 +-
 BaseTypeFactory.cc                                 |     4 +-
 BaseTypeFactory.h                                  |    23 +-
 Byte.cc                                            |    40 +-
 Byte.h                                             |    13 +-
 COPYRIGHT_URI                                      |     2 +-
 ChangeLog                                          |   384 +-
 Clause.h                                           |     8 +-
 Connect.cc                                         |    16 +-
 ConstraintEvaluator.cc                             |   109 +-
 ConstraintEvaluator.h                              |    82 +-
 Constructor.cc                                     |   230 +-
 Constructor.h                                      |    28 +-
 D4AsyncUtil.cc                                     |   357 +
 D4AsyncUtil.h                                      |    86 +
 D4ParseError.h => D4AttributeType.h                |    62 +-
 D4Attributes.cc                                    |   393 +
 D4Attributes.h                                     |   161 +
 D4BaseTypeFactory.cc                               |   129 +-
 D4BaseTypeFactory.h                                |    37 +-
 Connect.cc => D4Connect.cc                         |   841 +-
 D4Connect.h                                        |   112 +
 D4Dimensions.cc                                    |   139 +-
 D4Dimensions.h                                     |   194 +-
 D4Enum.cc                                          |   412 +
 D4Enum.h                                           |   281 +
 D4EnumDef.cc                                       |    79 -
 D4EnumDef.h                                        |    85 -
 D4EnumDefs.cc                                      |   136 +
 D4EnumDefs.h                                       |   170 +
 D4ParseError.h => D4Function.h                     |    39 +-
 D4Group.cc                                         |   549 +-
 D4Group.h                                          |   138 +-
 D4Maps.cc                                          |    56 +-
 D4Maps.h                                           |   112 +-
 D4Opaque.cc                                        |   158 +
 D4Opaque.h                                         |   102 +
 D4ParserSax2.cc                                    |  1428 +--
 D4ParserSax2.h                                     |   182 +-
 D4RValue.cc                                        |   218 +
 D4RValue.h                                         |   122 +
 D4Sequence.cc                                      |   525 +
 D4Sequence.h                                       |   272 +
 DAP4StreamMarshaller.cc => D4StreamMarshaller.cc   |   502 +-
 DAP4StreamMarshaller.h => D4StreamMarshaller.h     |   112 +-
 D4StreamUnMarshaller.cc                            |   475 +
 DAP4StreamUnMarshaller.h => D4StreamUnMarshaller.h |   108 +-
 DAP4StreamUnMarshaller.cc                          |   412 -
 DDS.cc                                             |   122 +-
 DDS.h                                              |    10 +-
 DDXParserSAX2.cc                                   |    57 +-
 DDXParserSAX2.h                                    |     2 +-
 DMR.cc                                             |   381 +
 DMR.h                                              |   185 +
 DODSFilter.cc                                      |    32 +-
 DODSFilter.h                                       |     2 +-
 DapIndent.cc                                       |     2 +
 DapObj.h                                           |    19 -
 DapXmlNamespaces.cc                                |     0
 DapXmlNamespaces.h                                 |   170 +
 Error.cc                                           |     4 -
 Error.lex                                          |     2 +-
 Error.tab.cc                                       |  1284 +--
 Error.tab.hh                                       |    74 +-
 EventHandler.h                                     |     8 +-
 Float32.cc                                         |    48 +-
 Float32.h                                          |    14 +-
 Float64.cc                                         |    46 +-
 Float64.h                                          |    12 +-
 GNU/GetOpt.cc                                      |     9 +-
 GNU/GetOpt.h                                       |    48 +-
 GNU/README                                         |     2 +-
 Grid.cc                                            |   644 +-
 Grid.h                                             |    34 +-
 HTTPCache.cc                                       |    17 +-
 HTTPCache.h                                        |     2 +
 HTTPCacheResponse.h                                |    11 +-
 HTTPConnect.cc                                     |   225 +-
 HTTPConnect.h                                      |    45 +-
 HTTPResponse.h                                     |   107 +-
 INSTALL                                            |    32 +-
 Int16.cc                                           |    47 +-
 Int16.h                                            |    14 +-
 Int32.cc                                           |    46 +-
 Int32.h                                            |    13 +-
 Int64.cc                                           |    67 +-
 Int64.h                                            |    21 +-
 Int8.cc                                            |    74 +-
 Int8.h                                             |    24 +-
 InternalErr.cc                                     |     4 -
 Makefile.am                                        |    96 +-
 Makefile.in                                        |   501 +-
 NEWS                                               |    31 +
 ObjectType.h                                       |    28 +-
 README                                             |    25 +
 README.dodsrc                                      |     2 +-
 RValue.cc                                          |    12 +-
 RValue.h                                           |     6 +-
 Response.h                                         |   107 +-
 ResponseTooBigErr.cc                               |     4 -
 Sequence.cc                                        |  1271 +--
 Sequence.h                                         |   475 +-
 ServerFunction.cc                                  |    40 +-
 ServerFunction.h                                   |   123 +-
 ServerFunctionsList.cc                             |   249 +-
 ServerFunctionsList.h                              |    37 +-
 SignalHandler.cc                                   |    22 +-
 SignalHandler.h                                    |     9 +-
 StdinResponse.h                                    |    40 +-
 Str.cc                                             |    49 +-
 Str.h                                              |    14 +-
 Structure.cc                                       |    42 +-
 Structure.h                                        |    65 +-
 Type.h                                             |   127 +
 UInt16.cc                                          |    48 +-
 UInt16.h                                           |    11 +-
 UInt32.cc                                          |    48 +-
 UInt32.h                                           |    11 +-
 UInt64.cc                                          |    67 +-
 UInt64.h                                           |    20 +-
 Url.cc                                             |     1 +
 VCPP/sample/getdap.cc                              |     4 +-
 Vector.cc                                          |  1395 ++-
 Vector.h                                           |    74 +-
 XDRFileMarshaller.cc                               |     2 +
 XDRFileUnMarshaller.cc                             |     2 +
 XDRStreamMarshaller.cc                             |    34 +-
 XDRUtils.cc                                        |     5 +-
 XMLWriter.cc                                       |     2 +
 XMLWriter.h                                        |    10 +-
 abi_checker.xml.in                                 |    17 +
 aclocal.m4                                         |    44 +-
 ce_expr.lex                                        |     2 -
 ce_expr.tab.cc                                     |  2264 ++--
 ce_expr.tab.hh                                     |    98 +-
 ce_expr.yy                                         |    52 +-
 chunked_istream.cc                                 |   414 +
 chunked_istream.h                                  |   172 +
 chunked_ostream.cc                                 |   339 +
 chunked_ostream.h                                  |   164 +
 chunked_stream.h                                   |    29 +
 conf/._compile                                     |   Bin 0 -> 240 bytes
 conf/._config.guess                                |   Bin 0 -> 240 bytes
 conf/._config.sub                                  |   Bin 0 -> 240 bytes
 conf/._depcomp                                     |   Bin 0 -> 240 bytes
 conf/._install-sh                                  |   Bin 0 -> 240 bytes
 conf/._libtool.m4                                  |   Bin 0 -> 240 bytes
 conf/._ltmain.sh                                   |   Bin 0 -> 240 bytes
 conf/._ltoptions.m4                                |   Bin 0 -> 240 bytes
 conf/._ltsugar.m4                                  |   Bin 0 -> 240 bytes
 conf/._ltversion.m4                                |   Bin 0 -> 240 bytes
 conf/._lt~obsolete.m4                              |   Bin 0 -> 240 bytes
 conf/._missing                                     |   Bin 0 -> 240 bytes
 conf/acinclude.m4                                  |     2 +-
 conf/compile                                       |   342 +
 conf/config.rpath                                  |   690 ++
 conf/gcov_valgrind.m4                              |    36 +
 conf/snippet/arg-nonnull.h                         |     2 +-
 conf/snippet/c++defs.h                             |     2 +-
 conf/snippet/warn-on-use.h                         |     4 +-
 config.h.in                                        |   213 +-
 configure                                          |  2363 ++++-
 configure.ac                                       |   224 +-
 crc.h                                              |    98 +
 ResponseTooBigErr.cc => d4_ce/D4CEScanner.h        |    60 +-
 d4_ce/D4ConstraintEvaluator.cc                     |   306 +
 d4_ce/D4ConstraintEvaluator.h                      |   132 +
 d4_ce/D4FunctionEvaluator.cc                       |   275 +
 d4_ce/D4FunctionEvaluator.h                        |   115 +
 ResponseTooBigErr.cc => d4_ce/D4FunctionScanner.h  |    60 +-
 d4_ce/Makefile.am                                  |   119 +
 {tests => d4_ce}/Makefile.in                       |   644 +-
 d4_ce/d4_ce_parser.tab.cc                          |  1836 ++++
 d4_ce/d4_ce_parser.tab.hh                          |   783 ++
 d4_ce/d4_ce_parser.yy                              |   410 +
 d4_ce/d4_ce_scanner.ll                             |   158 +
 d4_ce/d4_function_parser.tab.cc                    |  2446 +++++
 d4_ce/d4_function_parser.tab.hh                    |   835 ++
 d4_ce/d4_function_parser.yy                        |   494 +
 d4_ce/d4_function_scanner.ll                       |   184 +
 d4_ce/gen_grammar_sources/FlexLexer.h.tmp          |   206 +
 d4_ce/gen_grammar_sources/d4_ce_parser.tab.cc.tmp  |  1861 ++++
 d4_ce/gen_grammar_sources/d4_ce_parser.tab.hh.tmp  |   731 ++
 .../d4_function_parser.tab.cc.tmp                  |  2467 +++++
 .../d4_function_parser.tab.hh.tmp                  |   783 ++
 .../gen_grammar_sources/lex.d4_ce.cc.tmp           |  1590 +--
 .../gen_grammar_sources/lex.d4_function.cc.tmp     |  1639 +--
 d4_ce/gen_grammar_sources/location.hh.tmp          |   187 +
 d4_ce/gen_grammar_sources/position.hh.tmp          |   180 +
 d4_ce/gen_grammar_sources/stack.hh.tmp             |   158 +
 lex.ce_expr.cc => d4_ce/lex.d4_ce.cc               |  1590 +--
 lex.ce_expr.cc => d4_ce/lex.d4_function.cc         |  1639 +--
 d4_ce/location.hh                                  |   187 +
 d4_ce/position.hh                                  |   180 +
 d4_ce/stack.hh                                     |   158 +
 das.lex                                            |     2 +-
 das.tab.cc                                         |  1710 ++-
 das.tab.hh                                         |    78 +-
 das.yy                                             |     2 +-
 dds.tab.cc                                         |  1630 ++-
 dds.tab.hh                                         |    96 +-
 dods-datatypes-config.h.in                         |     3 +
 dods-datatypes-static.h                            |    24 +-
 dods-datatypes.h                                   |    24 +-
 dods-limits.h                                      |     1 +
 doxy.conf                                          |     2 +-
 doxy_private.conf                                  |     2 +-
 escaping.cc                                        |    14 +-
 expr.h                                             |    21 +-
 getdap.cc                                          |   122 +-
 getdap4.cc                                         |   401 +
 getdap4.man1                                       |    99 +
 gl/Makefile.am                                     |    75 +-
 gl/Makefile.in                                     |   154 +-
 gl/alloca.in.h                                     |     9 +-
 gl/btowc.c                                         |     2 +-
 gl/byteswap.in.h                                   |     2 +-
 gl/config.charset                                  |     2 +-
 gl/gettext.h                                       |    11 +-
 gl/glthread/lock.c                                 |  1057 ++
 gl/glthread/lock.h                                 |   927 ++
 gl/glthread/threadlib.c                            |    73 +
 gl/langinfo.in.h                                   |     2 +-
 gl/localcharset.c                                  |    14 +-
 gl/localcharset.h                                  |     2 +-
 gl/locale.in.h                                     |    21 +-
 gl/localeconv.c                                    |     2 +-
 gl/m4/00gnulib.m4                                  |     2 +-
 gl/m4/alloca.m4                                    |     2 +-
 gl/m4/btowc.m4                                     |     2 +-
 gl/m4/byteswap.m4                                  |     2 +-
 gl/m4/codeset.m4                                   |     2 +-
 gl/m4/configmake.m4                                |    13 +-
 gl/m4/eealloc.m4                                   |    31 +
 gl/m4/extensions.m4                                |    51 +-
 gl/m4/extern-inline.m4                             |    79 +
 gl/m4/fcntl-o.m4                                   |    15 +-
 gl/m4/glibc21.m4                                   |     2 +-
 gl/m4/gnulib-cache.m4                              |     4 +-
 gl/m4/gnulib-common.m4                             |     8 +-
 gl/m4/gnulib-comp.m4                               |   196 +-
 gl/m4/gnulib-tool.m4                               |     2 +-
 gl/m4/include_next.m4                              |     2 +-
 gl/m4/langinfo_h.m4                                |     2 +-
 gl/m4/lib-ld.m4                                    |   119 +
 gl/m4/lib-link.m4                                  |   777 ++
 gl/m4/lib-prefix.m4                                |   224 +
 gl/m4/localcharset.m4                              |     2 +-
 gl/m4/locale-fr.m4                                 |     2 +-
 gl/m4/locale-ja.m4                                 |     2 +-
 gl/m4/locale-zh.m4                                 |     2 +-
 gl/m4/locale_h.m4                                  |     2 +-
 gl/m4/localeconv.m4                                |     2 +-
 gl/m4/lock.m4                                      |    42 +
 gl/m4/longlong.m4                                  |     2 +-
 gl/m4/malloc.m4                                    |     2 +-
 gl/m4/mbrtowc.m4                                   |     2 +-
 gl/m4/mbsinit.m4                                   |     2 +-
 gl/m4/mbstate_t.m4                                 |     2 +-
 gl/m4/mbtowc.m4                                    |     2 +-
 gl/m4/multiarch.m4                                 |     2 +-
 gl/m4/nl_langinfo.m4                               |     2 +-
 gl/m4/off_t.m4                                     |     2 +-
 gl/m4/regex.m4                                     |    97 +-
 gl/m4/ssize_t.m4                                   |     2 +-
 gl/m4/stdbool.m4                                   |     2 +-
 gl/m4/stddef_h.m4                                  |     2 +-
 gl/m4/stdint.m4                                    |     2 +-
 gl/m4/stdlib_h.m4                                  |     9 +-
 gl/m4/strcase.m4                                   |    45 -
 gl/m4/strings_h.m4                                 |    52 -
 gl/m4/sys_types_h.m4                               |     6 +-
 gl/m4/threadlib.m4                                 |   371 +
 gl/m4/unistd_h.m4                                  |     6 +-
 gl/m4/warn-on-use.m4                               |     2 +-
 gl/m4/wchar_h.m4                                   |     2 +-
 gl/m4/wchar_t.m4                                   |     2 +-
 gl/m4/wcrtomb.m4                                   |     2 +-
 gl/m4/wctype_h.m4                                  |     6 +-
 gl/m4/wint_t.m4                                    |     2 +-
 gl/malloc.c                                        |     2 +-
 gl/mbrtowc.c                                       |     2 +-
 gl/mbsinit.c                                       |     2 +-
 gl/mbtowc-impl.h                                   |     2 +-
 gl/mbtowc.c                                        |     2 +-
 gl/nl_langinfo.c                                   |     2 +-
 gl/ref-add.sin                                     |     2 +-
 gl/ref-del.sin                                     |     2 +-
 gl/regcomp.c                                       |   165 +-
 gl/regex.c                                         |    22 +-
 gl/regex.h                                         |    23 +-
 gl/regex_internal.c                                |    37 +-
 gl/regex_internal.h                                |   130 +-
 gl/regexec.c                                       |    65 +-
 gl/stdbool.in.h                                    |    53 +-
 gl/stddef.in.h                                     |     2 +-
 gl/stdint.in.h                                     |     4 +-
 gl/stdlib.in.h                                     |    36 +-
 gl/strcasecmp.c                                    |    62 -
 gl/streq.h                                         |     2 +-
 gl/strings.in.h                                    |   122 -
 gl/strncasecmp.c                                   |    62 -
 gl/sys_types.in.h                                  |     2 +-
 gl/unistd.c                                        |     3 +
 gl/unistd.in.h                                     |    55 +-
 gl/verify.h                                        |   142 +-
 gl/wchar.in.h                                      |     2 +-
 gl/wcrtomb.c                                       |     2 +-
 gl/wctype-h.c                                      |     4 +
 gl/wctype.in.h                                     |    50 +-
 lex.Error.cc                                       |    56 +-
 lex.ce_expr.cc                                     |   128 +-
 lex.das.cc                                         |    56 +-
 lex.dds.cc                                         |    54 +-
 libdap.spec                                        |    36 +-
 ResponseTooBigErr.cc => media_types.h              |    44 +-
 mime_util.cc                                       |   134 +-
 mime_util.h                                        |    89 +-
 parser-util.cc                                     |    57 +-
 parser.h => parser-util.h                          |   118 +-
 parser.h                                           |    59 +-
 tests/D4ResponseBuilder.cc                         |   167 +
 tests/{ResponseBuilder.h => D4ResponseBuilder.h}   |    48 +-
 tests/D4TestFunction.cc                            |   187 +
 tests/D4TestFunction.h                             |    65 +
 tests/D4TestTypeFactory.cc                         |   252 +
 D4BaseTypeFactory.h => tests/D4TestTypeFactory.h   |    85 +-
 tests/DASTest                                      |    10 +-
 tests/DDSTest                                      |    10 +-
 tests/DMRTest                                      | 10475 +++++++++++++++++++
 tests/DMRTest.at                                   |   380 +
 tests/EXPRTest                                     |  2188 ++--
 tests/EXPRTest.at                                  |    52 +-
 tests/Makefile.am                                  |    84 +-
 tests/Makefile.in                                  |   542 +-
 tests/ResponseBuilder.cc                           |    85 +-
 tests/ResponseBuilder.h                            |    13 +-
 tests/TestArray.cc                                 |   492 +-
 tests/TestArray.h                                  |    20 +-
 tests/TestByte.cc                                  |    11 +-
 tests/TestByte.h                                   |    16 +-
 tests/TestCommon.cc                                |    24 -
 tests/TestCommon.h                                 |    43 +-
 tests/{TestUInt16.cc => TestD4Enum.cc}             |    80 +-
 tests/{TestStructure.h => TestD4Enum.h}            |    44 +-
 tests/{TestStructure.cc => TestD4Group.cc}         |    90 +-
 tests/{TestStructure.h => TestD4Group.h}           |    44 +-
 tests/TestD4Opaque.cc                              |   122 +
 tests/{TestStructure.h => TestD4Opaque.h}          |    47 +-
 tests/TestD4Sequence.cc                            |   120 +
 tests/{TestSequence.h => TestD4Sequence.h}         |    40 +-
 tests/TestFloat32.cc                               |     3 -
 tests/TestFunction.cc                              |   112 +
 tests/TestFunction.h                               |    60 +
 tests/TestInt16.cc                                 |    18 +-
 tests/TestInt32.cc                                 |    46 +-
 tests/{TestInt16.cc => TestInt64.cc}               |    64 +-
 tests/{TestStructure.h => TestInt64.h}             |    40 +-
 tests/TestInt8.cc                                  |   101 +
 tests/{TestStructure.h => TestInt8.h}              |    39 +-
 tests/TestSequence.cc                              |    88 +-
 tests/TestSequence.h                               |    20 +-
 tests/TestStr.cc                                   |    34 +-
 tests/TestStructure.cc                             |   140 +-
 tests/TestStructure.h                              |    16 +-
 tests/TestUInt16.cc                                |    20 +-
 tests/TestUInt32.cc                                |    18 +-
 tests/{TestUInt16.cc => TestUInt64.cc}             |    47 +-
 tests/{TestStructure.h => TestUInt64.h}            |    38 +-
 tests/atconfig                                     |     8 +-
 tests/dds-test.cc                                  |    32 +-
 tests/dmr-test.cc                                  |   476 +
 tests/dmr-testsuite/test_array_1.xml               |    13 +
 tests/dmr-testsuite/test_array_1.xml.1.func_base   |    20 +
 tests/dmr-testsuite/test_array_1.xml.2.func_base   |    20 +
 tests/dmr-testsuite/test_array_1.xml.3.func_base   |    20 +
 tests/dmr-testsuite/test_array_1.xml.4.func_base   |    20 +
 tests/dmr-testsuite/test_array_1.xml.5.func_base   |    20 +
 tests/dmr-testsuite/test_array_1.xml.6.func_base   |    20 +
 tests/dmr-testsuite/test_array_1.xml.7.func_base   |    20 +
 tests/dmr-testsuite/test_array_1.xml.baseline      |     8 +
 tests/dmr-testsuite/test_array_1.xml.send_base     |     9 +
 tests/dmr-testsuite/test_array_1.xml.trans_base    |    20 +
 tests/dmr-testsuite/test_array_10.xml              |    19 +
 tests/dmr-testsuite/test_array_10.xml.baseline     |    14 +
 tests/dmr-testsuite/test_array_10.xml.trans_base   |    35 +
 tests/dmr-testsuite/test_array_11.xml              |    25 +
 tests/dmr-testsuite/test_array_11.xml.baseline     |    19 +
 tests/dmr-testsuite/test_array_11.xml.trans_base   |    45 +
 tests/dmr-testsuite/test_array_1_data.bin          |   Bin 0 -> 543 bytes
 tests/dmr-testsuite/test_array_2.xml               |    14 +
 tests/dmr-testsuite/test_array_2.xml.baseline      |     9 +
 tests/dmr-testsuite/test_array_2.xml.send_base     |    10 +
 tests/dmr-testsuite/test_array_2.xml.trans_base    |    22 +
 tests/dmr-testsuite/test_array_2_data.bin          |   Bin 0 -> 627 bytes
 tests/dmr-testsuite/test_array_3.xml               |    13 +
 tests/dmr-testsuite/test_array_3.xml.baseline      |    10 +
 tests/dmr-testsuite/test_array_3.xml.send_base     |    11 +
 tests/dmr-testsuite/test_array_3.xml.trans_base    |    24 +
 tests/dmr-testsuite/test_array_3_data.bin          |   Bin 0 -> 1009 bytes
 tests/dmr-testsuite/test_array_4.xml               |    65 +
 tests/dmr-testsuite/test_array_4.xml.1.trans_base  |    66 +
 tests/dmr-testsuite/test_array_4.xml.2.trans_base  |    66 +
 tests/dmr-testsuite/test_array_4.xml.3.trans_base  |    66 +
 tests/dmr-testsuite/test_array_4.xml.4.trans_base  |    66 +
 tests/dmr-testsuite/test_array_4.xml.5.trans_base  |    80 +
 tests/dmr-testsuite/test_array_4.xml.6.trans_base  |    65 +
 tests/dmr-testsuite/test_array_4.xml.7.trans_base  |    65 +
 tests/dmr-testsuite/test_array_4.xml.8.trans_base  |    64 +
 tests/dmr-testsuite/test_array_4.xml.baseline      |    51 +
 tests/dmr-testsuite/test_array_4.xml.send_base     |    52 +
 tests/dmr-testsuite/test_array_4.xml.trans_base    |   136 +
 tests/dmr-testsuite/test_array_4_data.bin          |   Bin 0 -> 3009 bytes
 tests/dmr-testsuite/test_array_5.xml               |    31 +
 tests/dmr-testsuite/test_array_5.xml.1.func_base   |    38 +
 tests/dmr-testsuite/test_array_5.xml.2.func_base   |    38 +
 tests/dmr-testsuite/test_array_5.xml.3.func_base   |    38 +
 tests/dmr-testsuite/test_array_5.xml.4.func_base   |    38 +
 tests/dmr-testsuite/test_array_5.xml.baseline      |    23 +
 tests/dmr-testsuite/test_array_5.xml.send_base     |    24 +
 tests/dmr-testsuite/test_array_5.xml.trans_base    |    59 +
 tests/dmr-testsuite/test_array_5_data.bin          |   Bin 0 -> 1119 bytes
 tests/dmr-testsuite/test_array_6.1.xml             |    19 +
 .../dmr-testsuite/test_array_6.1.xml.1.trans_base  |    36 +
 .../dmr-testsuite/test_array_6.1.xml.2.trans_base  |    35 +
 .../dmr-testsuite/test_array_6.1.xml.3.trans_base  |    36 +
 .../dmr-testsuite/test_array_6.1.xml.4.trans_base  |    34 +
 tests/dmr-testsuite/test_array_6.2.xml             |    17 +
 .../dmr-testsuite/test_array_6.2.xml.1.trans_base  |    32 +
 .../dmr-testsuite/test_array_6.2.xml.2.trans_base  |    31 +
 .../dmr-testsuite/test_array_6.2.xml.3.trans_base  |    29 +
 .../dmr-testsuite/test_array_6.2.xml.4.trans_base  |    30 +
 .../dmr-testsuite/test_array_6.2.xml.5.trans_base  |    26 +
 tests/dmr-testsuite/test_array_6.xml               |    16 +
 tests/dmr-testsuite/test_array_6.xml.1.trans_base  |    30 +
 tests/dmr-testsuite/test_array_6.xml.2.trans_base  |    30 +
 tests/dmr-testsuite/test_array_6.xml.3.trans_base  |    29 +
 tests/dmr-testsuite/test_array_6.xml.baseline      |    13 +
 tests/dmr-testsuite/test_array_6.xml.send_base     |    14 +
 tests/dmr-testsuite/test_array_6.xml.trans_base    |    30 +
 tests/dmr-testsuite/test_array_6_data.bin          |   Bin 0 -> 783 bytes
 tests/dmr-testsuite/test_array_7.1.xml             |    17 +
 .../dmr-testsuite/test_array_7.1.xml.1.trans_base  |    32 +
 .../dmr-testsuite/test_array_7.1.xml.2.trans_base  |    31 +
 .../dmr-testsuite/test_array_7.1.xml.3.trans_base  |    29 +
 .../dmr-testsuite/test_array_7.1.xml.4.trans_base  |    29 +
 .../dmr-testsuite/test_array_7.1.xml.5.trans_base  |    32 +
 .../dmr-testsuite/test_array_7.1.xml.6.trans_base  |    31 +
 tests/dmr-testsuite/test_array_7.2.xml             |    18 +
 .../dmr-testsuite/test_array_7.2.xml.1.trans_base  |    33 +
 .../dmr-testsuite/test_array_7.2.xml.2.trans_base  |    32 +
 .../dmr-testsuite/test_array_7.2.xml.3.trans_base  |    33 +
 .../dmr-testsuite/test_array_7.2.xml.4.trans_base  |    32 +
 tests/dmr-testsuite/test_array_7.xml               |    13 +
 tests/dmr-testsuite/test_array_7.xml.1.trans_base  |    24 +
 tests/dmr-testsuite/test_array_7.xml.2.trans_base  |    23 +
 tests/dmr-testsuite/test_array_7.xml.3.trans_base  |    24 +
 tests/dmr-testsuite/test_array_7.xml.4.trans_base  |    23 +
 tests/dmr-testsuite/test_array_7.xml.baseline      |    10 +
 tests/dmr-testsuite/test_array_7.xml.trans_base    |    24 +
 tests/dmr-testsuite/test_array_8.xml               |    13 +
 tests/dmr-testsuite/test_array_8.xml.1.trans_base  |    27 +
 tests/dmr-testsuite/test_array_8.xml.baseline      |    12 +
 tests/dmr-testsuite/test_array_8.xml.trans_base    |    28 +
 tests/dmr-testsuite/test_escaped_paths.xml         |    69 +
 tests/dmr-testsuite/test_simple_1.xml              |    11 +
 tests/dmr-testsuite/test_simple_1.xml.baseline     |     6 +
 tests/dmr-testsuite/test_simple_1.xml.send_base    |     7 +
 tests/dmr-testsuite/test_simple_1.xml.trans_base   |    17 +
 tests/dmr-testsuite/test_simple_10.xml             |     9 +
 tests/dmr-testsuite/test_simple_10.xml.baseline    |     6 +
 tests/dmr-testsuite/test_simple_10.xml.trans_base  |    17 +
 tests/dmr-testsuite/test_simple_1_data.bin         |   Bin 0 -> 493 bytes
 tests/dmr-testsuite/test_simple_2.xml              |    28 +
 tests/dmr-testsuite/test_simple_2.xml.baseline     |    18 +
 tests/dmr-testsuite/test_simple_2.xml.send_base    |    19 +
 tests/dmr-testsuite/test_simple_2.xml.trans_base   |    89 +
 tests/dmr-testsuite/test_simple_2_data.bin         |   Bin 0 -> 955 bytes
 tests/dmr-testsuite/test_simple_3.xml              |    13 +
 tests/dmr-testsuite/test_simple_3.xml.baseline     |    10 +
 tests/dmr-testsuite/test_simple_3.xml.send_base    |    11 +
 tests/dmr-testsuite/test_simple_3.xml.trans_base   |    25 +
 tests/dmr-testsuite/test_simple_3_data.bin         |   Bin 0 -> 610 bytes
 tests/dmr-testsuite/test_simple_3_error_1.xml      |    13 +
 .../test_simple_3_error_1.xml.baseline             |     2 +
 tests/dmr-testsuite/test_simple_3_error_2.xml      |    13 +
 .../test_simple_3_error_2.xml.baseline             |     3 +
 tests/dmr-testsuite/test_simple_3_error_3.xml      |    13 +
 .../test_simple_3_error_3.xml.baseline             |     2 +
 tests/dmr-testsuite/test_simple_4.xml              |    15 +
 tests/dmr-testsuite/test_simple_4.xml.baseline     |    10 +
 tests/dmr-testsuite/test_simple_4.xml.send_base    |    11 +
 tests/dmr-testsuite/test_simple_4.xml.trans_base   |    24 +
 tests/dmr-testsuite/test_simple_4_data.bin         |   Bin 0 -> 617 bytes
 tests/dmr-testsuite/test_simple_5.xml              |    20 +
 tests/dmr-testsuite/test_simple_5.xml.baseline     |    14 +
 tests/dmr-testsuite/test_simple_5.xml.send_base    |    15 +
 tests/dmr-testsuite/test_simple_5.xml.trans_base   |    65 +
 tests/dmr-testsuite/test_simple_5_data.bin         |   Bin 0 -> 735 bytes
 tests/dmr-testsuite/test_simple_6.1.xml            |    15 +
 .../dmr-testsuite/test_simple_6.1.xml.1.trans_base |    26 +
 tests/dmr-testsuite/test_simple_6.xml              |    12 +
 tests/dmr-testsuite/test_simple_6.xml.1.trans_base |    22 +
 tests/dmr-testsuite/test_simple_6.xml.2.trans_base |    21 +
 tests/dmr-testsuite/test_simple_6.xml.3.trans_base |    21 +
 tests/dmr-testsuite/test_simple_6.xml.baseline     |     9 +
 tests/dmr-testsuite/test_simple_6.xml.trans_base   |    22 +
 tests/dmr-testsuite/test_simple_7.xml              |    12 +
 tests/dmr-testsuite/test_simple_7.xml.1.trans_base |    22 +
 tests/dmr-testsuite/test_simple_7.xml.2.trans_base |    21 +
 tests/dmr-testsuite/test_simple_7.xml.baseline     |     9 +
 tests/dmr-testsuite/test_simple_7.xml.trans_base   |    22 +
 tests/dmr-testsuite/test_simple_8.1.xml            |    16 +
 tests/dmr-testsuite/test_simple_8.xml              |    14 +
 tests/dmr-testsuite/test_simple_8.xml.1.trans_base |    26 +
 tests/dmr-testsuite/test_simple_8.xml.2.trans_base |    25 +
 tests/dmr-testsuite/test_simple_8.xml.baseline     |    11 +
 tests/dmr-testsuite/test_simple_8.xml.trans_base   |    26 +
 tests/dmr-testsuite/test_simple_9.1.xml            |    24 +
 tests/dmr-testsuite/test_simple_9.1.xml.baseline   |    18 +
 tests/dmr-testsuite/test_simple_9.1.xml.trans_base |    45 +
 tests/dmr-testsuite/test_simple_9.2.xml            |    25 +
 tests/dmr-testsuite/test_simple_9.xml              |    15 +
 tests/dmr-testsuite/test_simple_9.xml.baseline     |    11 +
 tests/dmr-testsuite/test_simple_9.xml.trans_base   |    27 +
 tests/dmr-testsuite/vol_1_ce_1.xml                 |    16 +
 tests/dmr-testsuite/vol_1_ce_1.xml.1.func_base     |    22 +
 tests/dmr-testsuite/vol_1_ce_1.xml.10.func_base    |    23 +
 tests/dmr-testsuite/vol_1_ce_1.xml.11.func_base    |    23 +
 tests/dmr-testsuite/vol_1_ce_1.xml.12.func_base    |    23 +
 tests/dmr-testsuite/vol_1_ce_1.xml.13.func_base    |    23 +
 tests/dmr-testsuite/vol_1_ce_1.xml.14.func_base    |    23 +
 tests/dmr-testsuite/vol_1_ce_1.xml.15.func_base    |    23 +
 tests/dmr-testsuite/vol_1_ce_1.xml.16.func_base    |    23 +
 tests/dmr-testsuite/vol_1_ce_1.xml.2.func_base     |    22 +
 tests/dmr-testsuite/vol_1_ce_1.xml.3.func_base     |    22 +
 tests/dmr-testsuite/vol_1_ce_1.xml.4.func_base     |    22 +
 tests/dmr-testsuite/vol_1_ce_1.xml.5.func_base     |    22 +
 tests/dmr-testsuite/vol_1_ce_1.xml.6.func_base     |    22 +
 tests/dmr-testsuite/vol_1_ce_1.xml.7.func_base     |    23 +
 tests/dmr-testsuite/vol_1_ce_1.xml.8.func_base     |    23 +
 tests/dmr-testsuite/vol_1_ce_1.xml.9.func_base     |    23 +
 tests/dmr-testsuite/vol_1_ce_10.xml                |    21 +
 tests/dmr-testsuite/vol_1_ce_10.xml.1.func_base    |    30 +
 tests/dmr-testsuite/vol_1_ce_10.xml.2.func_base    |    37 +
 tests/dmr-testsuite/vol_1_ce_10.xml.3.func_base    |    37 +
 tests/dmr-testsuite/vol_1_ce_11.xml                |    24 +
 tests/dmr-testsuite/vol_1_ce_12.xml                |    26 +
 tests/dmr-testsuite/vol_1_ce_2.xml                 |    19 +
 tests/dmr-testsuite/vol_1_ce_2.xml.1.func_base     |    15 +
 tests/dmr-testsuite/vol_1_ce_3.xml                 |    22 +
 tests/dmr-testsuite/vol_1_ce_4.xml                 |    23 +
 tests/dmr-testsuite/vol_1_ce_5.xml                 |    27 +
 tests/dmr-testsuite/vol_1_ce_6.xml                 |    33 +
 tests/dmr-testsuite/vol_1_ce_7.xml                 |    46 +
 tests/dmr-testsuite/vol_1_ce_8.xml                 |    27 +
 tests/dmr-testsuite/vol_1_ce_9.xml                 |    36 +
 tests/expr-test.cc                                 |    23 +-
 tests/expr-testsuite/test.5.func3.base             |    16 +
 tests/expr-testsuite/test.5.func4.base             |    16 +
 tests/expr-testsuite/test.6.func1.base             |     7 +
 tests/expr-testsuite/test.6.func2.base             |     7 +
 tests/expr-testsuite/test.6.func3.base             |    14 +
 tests/expr-testsuite/test.f                        |     9 +
 tests/expr-testsuite/test.fa.base                  |    14 +
 tests/expr-testsuite/test.fb.base                  |    14 +
 tests/getdap-testsuite/fnoc1.nc.dds                |     7 +
 tests/getdapTest                                   |  2034 ++++
 tests/getdapTest.at                                |    34 +
 tests/package.m4                                   |     4 +-
 unit-tests/AttrTableTest.cc                        |    64 +-
 unit-tests/D4-marshaller/test_cmp.dat              |   Bin 0 -> 16 bytes
 unit-tests/D4-marshaller/test_opaque_1_bin.dat     |   Bin 0 -> 32780 bytes
 unit-tests/D4-marshaller/test_opaque_1_bin.dat.sav |   Bin 0 -> 32787 bytes
 unit-tests/D4-marshaller/test_scalars_1.dat        |   Bin 0 -> 253 bytes
 unit-tests/D4-marshaller/test_scalars_1_bin.dat    |   Bin 0 -> 57 bytes
 unit-tests/D4-marshaller/test_scalars_2.dat        |   Bin 0 -> 76 bytes
 unit-tests/D4-marshaller/test_scalars_2_bin.dat    |   Bin 0 -> 20 bytes
 unit-tests/D4-marshaller/test_scalars_3_bin.dat    |   Bin 0 -> 101 bytes
 unit-tests/D4-marshaller/test_vector_1_bin.dat     |   Bin 0 -> 425996 bytes
 unit-tests/D4-marshaller/test_vector_2_bin.dat     |   Bin 0 -> 426005 bytes
 unit-tests/D4-xml/D4AsyncAccepted.xml              |     6 +
 unit-tests/D4-xml/D4AsyncAccepted_StyleRef.xml     |     7 +
 unit-tests/D4-xml/D4AsyncGone.xml                  |     2 +
 unit-tests/D4-xml/D4AsyncGone_StyleRef.xml         |     3 +
 unit-tests/D4-xml/D4AsyncPending.xml               |     2 +
 unit-tests/D4-xml/D4AsyncPending_StyleRef.xml      |     3 +
 unit-tests/D4-xml/D4AsyncRejected.xml              |     5 +
 unit-tests/D4-xml/D4AsyncRejected_StyleRef.xml     |     6 +
 unit-tests/D4-xml/D4AsyncRequired.xml              |     5 +
 unit-tests/D4-xml/D4AsyncRequired_StyleRef.xml     |     6 +
 unit-tests/D4-xml/D4Attributes_1.xml               |     5 +
 unit-tests/D4-xml/D4Attributes_2.xml               |     8 +
 unit-tests/D4-xml/D4Attributes_3.xml               |    27 +
 unit-tests/D4-xml/D4Attributes_assignment.xml      |     8 +
 unit-tests/D4-xml/D4Attributes_assignment_2.xml    |    27 +
 unit-tests/D4-xml/D4Attributes_copy_ctor.xml       |     8 +
 unit-tests/D4-xml/D4Attributes_empty.xml           |     1 +
 unit-tests/D4-xml/D4Attributes_values_1.xml        |     5 +
 unit-tests/D4-xml/D4Dimensions_3.xml               |     2 +-
 unit-tests/D4-xml/D4Dimensions_4.xml               |     2 +-
 unit-tests/D4-xml/D4Enum_1.xml                     |     2 +
 unit-tests/D4-xml/D4Enum_2.txt                     |     1 +
 unit-tests/D4-xml/D4Group_empty.xml                |     1 +
 unit-tests/D4-xml/D4Group_everything.xml           |    29 +
 unit-tests/D4-xml/D4Group_named_empty.xml          |     2 +
 unit-tests/D4-xml/D4Group_named_with_scalars.xml   |     5 +
 .../D4Group_named_with_scalars_and_stuff.xml       |    16 +
 unit-tests/D4-xml/D4Group_with_scalars.xml         |     3 +
 .../D4-xml/D4Group_with_scalars_and_stuff.xml      |    14 +
 unit-tests/D4-xml/DMR_0.1.xml                      |    28 +
 unit-tests/D4-xml/DMR_0.1_baseline.xml             |    22 +
 unit-tests/D4-xml/DMR_0.xml                        |    12 +
 unit-tests/D4-xml/DMR_0_baseline.xml               |     8 +
 unit-tests/D4-xml/DMR_1.xml                        |     9 +
 unit-tests/D4-xml/DMR_1_baseline.xml               |     4 +
 unit-tests/D4-xml/DMR_2.1.xml                      |    16 +
 unit-tests/D4-xml/DMR_2.1_baseline.xml             |     9 +
 unit-tests/D4-xml/DMR_2.xml                        |    14 +
 unit-tests/D4-xml/DMR_2_baseline.xml               |     9 +
 unit-tests/D4-xml/DMR_3.1.xml                      |    36 +
 unit-tests/D4-xml/DMR_3.1_baseline.xml             |    30 +
 unit-tests/D4-xml/DMR_3.2.xml                      |    10 +
 unit-tests/D4-xml/DMR_3.2_baseline.xml             |     6 +
 unit-tests/D4-xml/DMR_3.3.xml                      |    38 +
 unit-tests/D4-xml/DMR_3.3_baseline.xml             |    32 +
 unit-tests/D4-xml/DMR_3.4.xml                      |    17 +
 unit-tests/D4-xml/DMR_3.4_baseline.xml             |    13 +
 unit-tests/D4-xml/DMR_3.5.xml                      |    44 +
 unit-tests/D4-xml/DMR_3.5_baseline.xml             |    37 +
 unit-tests/D4-xml/DMR_3.xml                        |    14 +
 unit-tests/D4-xml/DMR_3_baseline.xml               |    10 +
 unit-tests/D4-xml/DMR_4.1.xml                      |    19 +
 unit-tests/D4-xml/DMR_4.1_baseline.xml             |    12 +
 unit-tests/D4-xml/DMR_4.xml                        |    30 +
 unit-tests/D4-xml/DMR_4_baseline.xml               |    25 +
 unit-tests/D4-xml/DMR_5.1.xml                      |    54 +
 unit-tests/D4-xml/DMR_5.1_baseline.xml             |    53 +
 unit-tests/D4-xml/DMR_5.xml                        |    31 +
 unit-tests/D4-xml/DMR_5_baseline.xml               |    27 +
 unit-tests/D4-xml/DMR_6.1.xml                      |    43 +
 unit-tests/D4-xml/DMR_6.1_baseline.xml             |    39 +
 unit-tests/D4-xml/DMR_6.2.xml                      |    49 +
 unit-tests/D4-xml/DMR_6.2_baseline.xml             |    37 +
 unit-tests/D4-xml/DMR_6.xml                        |    33 +
 unit-tests/D4-xml/DMR_6_baseline.xml               |    29 +
 unit-tests/D4-xml/DMR_7.1.xml                      |    47 +
 unit-tests/D4-xml/DMR_7.1_baseline.xml             |    42 +
 unit-tests/D4-xml/DMR_7.2.xml                      |    23 +
 unit-tests/D4-xml/DMR_7.2_baseline.xml             |    16 +
 unit-tests/D4-xml/DMR_7.3.xml                      |    39 +
 unit-tests/D4-xml/DMR_7.3_baseline.xml             |    28 +
 unit-tests/D4-xml/DMR_7.4.xml                      |    63 +
 unit-tests/D4-xml/DMR_7.4_baseline.xml             |    41 +
 unit-tests/D4-xml/DMR_7.5.xml                      |    24 +
 unit-tests/D4-xml/DMR_7.5_baseline.xml             |    16 +
 unit-tests/D4-xml/DMR_7.xml                        |    12 +
 unit-tests/D4-xml/DMR_7_baseline.xml               |     7 +
 unit-tests/D4-xml/DMR_8.xml                        |    18 +
 unit-tests/D4-xml/DMR_8_baseline.xml               |    11 +
 unit-tests/D4-xml/DMR_empty.xml                    |     7 +
 unit-tests/D4-xml/DMR_empty_baseline.xml           |     2 +
 unit-tests/D4-xml/Data_DMR_3.xml                   |    17 +
 unit-tests/D4-xml/README                           |     3 +
 unit-tests/D4-xml/coads_climatology.nc.xml         |   118 +
 unit-tests/D4AsyncDocTest.cc                       |   347 +
 unit-tests/D4AttributesTest.cc                     |   308 +
 unit-tests/D4DimensionsTest.cc                     |   128 +-
 unit-tests/D4EnumDefsTest.cc                       |    42 +-
 unit-tests/D4EnumTest.cc                           |   251 +
 unit-tests/D4GroupTest.cc                          |   382 +
 .../{DAP4MarshallerTest.cc => D4MarshallerTest.cc} |   188 +-
 unit-tests/D4ParserSax2Test.cc                     |   379 +
 ...P4UnMarshallerTest.cc => D4UnMarshallerTest.cc} |   240 +-
 unit-tests/DDSTest.cc                              |    78 +-
 unit-tests/DDXParserTest.cc                        |  1100 +-
 unit-tests/DMRTest.cc                              |   326 +
 unit-tests/HTTPCacheTest.cc                        |  1387 +--
 unit-tests/HTTPConnectTest.cc                      |   366 +-
 unit-tests/MIMEUtilTest.cc                         |     7 +-
 unit-tests/Makefile.am                             |    82 +-
 unit-tests/Makefile.in                             |   289 +-
 unit-tests/MarshallerTest.cc                       |    42 +-
 unit-tests/RCReaderTest.cc                         |   446 +-
 unit-tests/SequenceTest.cc                         |   197 +-
 unit-tests/ServerFunctionsListUnitTest.cc          |     6 +-
 unit-tests/SignalHandlerTest.cc                    |   179 +-
 unit-tests/arrayT.cc                               |     9 +-
 unit-tests/cache-testsuite/Makefile.in             |    42 +-
 .../cgi-util-tests/multipart_mime_header1.txt      |     2 +-
 unit-tests/chunked-io/test_big_binary_file.bin     |   Bin 0 -> 406032 bytes
 .../chunked-io/test_big_binary_file.bin.chunked    |   Bin 0 -> 464044 bytes
 .../chunked-io/test_big_binary_file.bin.plain      |   Bin 0 -> 406032 bytes
 unit-tests/chunked-io/test_big_binary_file_2.bin   |   Bin 0 -> 65550 bytes
 .../chunked-io/test_big_binary_file_2.bin.chunked  |   Bin 0 -> 62 bytes
 .../chunked-io/test_big_binary_file_2.bin.plain    |   Bin 0 -> 24 bytes
 unit-tests/chunked-io/test_big_binary_file_3.bin   |   Bin 0 -> 425996 bytes
 unit-tests/chunked-io/test_small_text_file.txt     |     1 +
 .../chunked-io/test_small_text_file.txt.chunked    |   Bin 0 -> 29 bytes
 .../chunked-io/test_small_text_file.txt.plain      |     1 +
 unit-tests/chunked-io/test_text_file.txt           |   370 +
 unit-tests/chunked-io/test_text_file.txt.chunked   |   Bin 0 -> 12913 bytes
 unit-tests/chunked-io/test_text_file.txt.plain     |   370 +
 unit-tests/chunked_iostream_test.cc                |   564 +
 unit-tests/dds-testsuite/3B42.980909.5.HDF.dmr     |    20 +
 .../3B42.980909.5.hacked.2.HDF.attr.dmr            |    59 +
 .../dds-testsuite/3B42.980909.5.hacked.2.HDF.das   |    34 +
 unit-tests/dds-testsuite/S2000415.HDF.dmr          |    89 +
 unit-tests/dds-testsuite/coads_climatology.nc.dmr  |    47 +
 unit-tests/dds-testsuite/dds-test.0/test.16.exp    |     2 +-
 unit-tests/dds-testsuite/dds-test.0/test.17.exp    |     2 +-
 unit-tests/dds-testsuite/dds-test.0/test.18.exp    |     2 +-
 unit-tests/dds-testsuite/dds-test.0/test.19.exp    |     2 +-
 unit-tests/dds-testsuite/dds-test.0/test.20.exp    |     2 +-
 unit-tests/dds-testsuite/fnoc1.nc.dmr              |    26 +
 unit-tests/dds-testsuite/test.1.attr.dmr           |    22 +
 unit-tests/dds-testsuite/test.1.das                |    11 +
 unit-tests/dds-testsuite/test.1.dmr                |     6 +
 unit-tests/ddsT.cc                                 |     9 +-
 .../ddx-testsuite/dataddx_without_top_headers.dap  |   Bin 1712 -> 1716 bytes
 unit-tests/generalUtilTest.cc                      |   407 +-
 unit-tests/structT.cc                              |     1 +
 unit-tests/testFile.cc                             |     3 +
 unit-tests/test_config.h                           |     2 +-
 util.cc                                            |   353 +-
 util.h                                             |     5 +
 xdr-datatypes.h                                    |     4 +-
 733 files changed, 75923 insertions(+), 20144 deletions(-)

diff --git a/AlarmHandler.h b/AlarmHandler.h
index 1600e18..f59459c 100644
--- a/AlarmHandler.h
+++ b/AlarmHandler.h
@@ -46,20 +46,20 @@ class AlarmHandler : public EventHandler
 {
 private:
     FILE *d_file;  // Sink for the Error object.
-    ostream &d_stream;
+    // TODO Remove: not used. jhrg 10/17/13 ostream &d_stream;
     string d_version;
 
     // Ensure that d_stream gets initialized...
-    AlarmHandler() : d_file( 0 ), d_stream( cout )
+    AlarmHandler() : d_file( 0 )// , d_stream( cout )
     {}
 
 public:
-    AlarmHandler(FILE *s) : d_file(s), d_stream( cout )
+    AlarmHandler(FILE *s) : d_file(s)//, d_stream( cout )
     {}
 
     /** Store information to be used by the handler.
     @param out Write to this stream. */
-    AlarmHandler(ostream &out) : d_file(0), d_stream( out )
+    AlarmHandler(ostream &) : d_file(0)//, d_stream( out )
     {}
 
     virtual ~AlarmHandler()
diff --git a/Array.cc b/Array.cc
index 212e39e..453f49d 100644
--- a/Array.cc
+++ b/Array.cc
@@ -33,14 +33,25 @@
 //
 // jhrg 9/13/94
 
-
 #include "config.h"
 
+// #define DODS_DEBUG
+
 #include <algorithm>
 #include <functional>
 #include <sstream>
 
 #include "Array.h"
+
+#include "D4Attributes.h"
+#include "DMR.h"
+#include "D4Dimensions.h"
+#include "D4Maps.h"
+#include "D4Group.h"
+#include "D4EnumDefs.h"
+#include "D4Enum.h"
+#include "XMLWriter.h"
+
 #include "util.h"
 #include "debug.h"
 #include "InternalErr.h"
@@ -50,10 +61,29 @@ using namespace std;
 
 namespace libdap {
 
+Array::dimension::dimension(D4Dimension *d) : dim(d), use_sdim_for_slice(true) {
+	size = d->size();
+	name = d->name();
+
+    start = 0;
+    stop = size - 1;
+    stride = 1;
+    c_size = size;
+}
+
 void
 Array::_duplicate(const Array &a)
 {
     _shape = a._shape;
+
+    // Deep copy the Maps if they are being used.
+    if (a.d_maps) {
+    	d_maps = new D4Maps(*(a.d_maps));
+    }
+    else {
+    	d_maps = 0;
+    }
+    // d_maps = a.d_maps ? new D4Maps(*(a.d_maps)) : 0;
 }
 
 // The first method of calculating length works when only one dimension is
@@ -97,7 +127,8 @@ Array::update_length(int)
     in the Array. May be null and set later using add_var() or add_var_nocopy()
     @brief Array constructor
 */
-Array::Array(const string &n, BaseType *v) : Vector(n, 0, dods_array_c)
+Array::Array(const string &n, BaseType *v, bool is_dap4 /* default:false */)
+	: Vector(n, 0, dods_array_c, is_dap4), d_maps(0)
 {
     add_var(v); // Vector::add_var() stores null if v is null
 }
@@ -115,10 +146,10 @@ Array::Array(const string &n, BaseType *v) : Vector(n, 0, dods_array_c)
     in the Array.
     @brief Array constructor
 */
-Array::Array(const string &n, const string &d, BaseType *v)
-    : Vector(n, d, 0, dods_array_c)
+Array::Array(const string &n, const string &d, BaseType *v, bool is_dap4 /* default:false */)
+    : Vector(n, d, 0, dods_array_c, is_dap4), d_maps(0)
 {
-    add_var(v); // Vector::add_var() stores null is v is null
+    add_var(v); // Vector::add_var() stores null if v is null
 }
 
 /** @brief The Array copy constructor. */
@@ -130,8 +161,7 @@ Array::Array(const Array &rhs) : Vector(rhs)
 /** @brief The Array destructor. */
 Array::~Array()
 {
-    DBG(cerr << "Entering ~Array (" << this << ")" << endl);
-    DBG(cerr << "Exiting ~Array" << endl);
+	delete d_maps;
 }
 
 BaseType *
@@ -153,6 +183,82 @@ Array::operator=(const Array &rhs)
     return *this;
 }
 
+BaseType *
+Array::transform_to_dap4(D4Group *root, Constructor */*container*/)
+{
+	Array *dest = static_cast<Array*>(ptr_duplicate());
+
+	// Process the Array's dimensions, making D4 shared dimensions for
+	// D2 dimensions that are named. If there is just a size, don't make
+	// a D4Dimension (In DAP4 you cannot share a dimension unless it has
+	// a name). jhrg 3/18/14
+
+	D4Dimensions *dims = root->dims();
+	for (Array::Dim_iter d = dest->dim_begin(), e = dest->dim_end(); d != e; ++d) {
+		if (!(*d).name.empty()) {
+			// If a D4Dimension with the name already exists, use it.
+			D4Dimension *d4_dim = dims->find_dim((*d).name);
+			if (!d4_dim) {
+				d4_dim = new D4Dimension((*d).name, (*d).size);
+				dims->add_dim_nocopy(d4_dim);
+			}
+			// TODO Revisit this decision. jhrg 3/18/14
+			// ...in case the name/size are different, make a unique D4Dimension
+			// but don't fiddle with the name. Not sure I like this idea, so I'm
+			// making the case explicit (could be rolled in to the block above).
+			// jhrg 3/18/14
+			//
+			// This is causing problems in the FITS handler because there are cases
+			// where two arrays have dimensions with the same name but different
+			// sizes. The deserializing code is using the first size listed, which is
+			// wrong in some cases. I'm going to try making this new D4Dimension using
+			// the dim name along with the variable name. jhrg 8/15/14
+			else if (d4_dim->size() != (unsigned long) (*d).size) {
+				d4_dim = new D4Dimension((*d).name + "_" + name(), (*d).size);
+				dims->add_dim_nocopy(d4_dim);
+			}
+			// At this point d4_dim's name and size == those of (*d) so just set
+			// the D4Dimension pointer so it matches the one in the D4Group.
+			(*d).dim = d4_dim;
+		}
+	}
+
+	// Copy the D2 attributes to D4 Attributes
+	dest->attributes()->transform_to_dap4(get_attr_table());
+
+	dest->set_is_dap4(true);
+
+	return dest;
+}
+
+/**
+ * Hackery that helps build a new D4Group from an old one. We need to re-wire the
+ * D4Dimension (note the lack of an 's' at then end) that the copied Array objects
+ * hold. This code does that. Note that these are 'weak pointers' so they should
+ * never be freed - the D4Group object will take care of that.
+ *
+ * @note The order of the D4Dimension instances matches in 'old_dims' and 'new_dims'.
+ *
+ * @param old_dims The Old D4Dimension objects (held in a D4Dimensions instance)
+ * @param new_dims The New D4Dimension objects.
+ */
+void
+Array::update_dimension_pointers(D4Dimensions *old_dims, D4Dimensions *new_dims)
+{
+	std::vector<dimension>::iterator i = _shape.begin(), e = _shape.end();
+	while (i != e) {
+		D4Dimensions::D4DimensionsIter old_i = old_dims->dim_begin(), old_e = old_dims->dim_end();
+		while (old_i != old_e) {
+			if ((*i).dim == *old_i) {
+				(*i).dim =  new_dims->find_dim((*old_i)->name());
+			}
+			++old_i;
+		}
+
+		++i;
+	}
+}
+
 /** @brief Add the BaseType pointer to this constructor type
     instance.
 
@@ -180,10 +286,6 @@ Array::operator=(const Array &rhs)
 void
 Array::add_var(BaseType *v, Part)
 {
-#if 0
-    if (v && v->is_dap4_only_type())
-        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Array.");
-#endif
     // If 'v' is an Array, add the template instance to this object and
     // then copy the dimension information. Odd semantics; I wonder if this
     //is ever used. jhrg 6/13/12
@@ -206,10 +308,6 @@ Array::add_var(BaseType *v, Part)
 void
 Array::add_var_nocopy(BaseType *v, Part)
 {
-#if 0
-    if (v && v->is_dap4_only_type())
-        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Array.");
-#endif
     // If 'v' is an Array, add the template instance to this object and
     // then copy the dimension information. Odd semantics; I wonder if this
     //is ever used. jhrg 6/13/12
@@ -240,23 +338,21 @@ Array::add_var_nocopy(BaseType *v, Part)
     an empty string.
     @brief Add a dimension of a given size. */
 void
-Array::append_dim(int size, string name)
+Array::append_dim(int size, const string &name)
 {
-    dimension d;
-
-    // This is invariant
-    d.size = size;
-    d.name = www2id(name);
+    dimension d(size, www2id(name));
+    _shape.push_back(d);
 
-    // this information changes with each constraint expression
-    d.start = 0;
-    d.stop = size - 1;
-    d.stride = 1;
-    d.c_size = size;
+    update_length();
+}
 
+void
+Array::append_dim(D4Dimension *dim)
+{
+	dimension d(/*dim->size(), www2id(dim->name()),*/ dim);
     _shape.push_back(d);
 
-    update_length(size);
+    update_length();
 }
 
 /** Creates a new OUTER dimension (slowest varying in rowmajor)
@@ -267,22 +363,21 @@ Array::append_dim(int size, string name)
 void
 Array::prepend_dim(int size, const string& name/* = "" */)
 {
-  dimension d;
-
-  // This is invariant
-  d.size = size;
-  d.name = www2id(name);
+  dimension d(size, www2id(name));
+  // Shifts the whole array, but it's tiny in general
+  _shape.insert(_shape.begin(), d);
 
-  // this information changes with each constraint expression
-  d.start = 0;
-  d.stop = size - 1;
-  d.stride = 1;
-  d.c_size = size;
+  update_length(); // the number is ignored...
+}
 
+void
+Array::prepend_dim(D4Dimension *dim)
+{
+  dimension d(/*dim->size(), www2id(dim->name()),*/ dim);
   // Shifts the whole array, but it's tiny in general
   _shape.insert(_shape.begin(), d);
 
-  update_length(size); // the number is ignored...
+  update_length(); // the number is ignored...
 }
 
 /** Remove all the dimensions currently set for the Array. This also
@@ -310,7 +405,7 @@ Array::reset_constraint()
         (*i).stride = 1;
         (*i).c_size = (*i).size;
 
-        update_length((*i).size);
+        update_length();
     }
 }
 
@@ -352,7 +447,8 @@ specified do not match the array variable.";
     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.
+    @param stop The stop index of the constraint. A value of -1 indicates
+    'to the end' of the array.
     @exception Error Thrown if the any of values of start, stop or stride
     cannot be applied to this array. */
 void
@@ -383,7 +479,24 @@ Array::add_constraint(Dim_iter i, int start, int stride, int stop)
 
     DBG(cerr << "add_constraint: c_size = " << d.c_size << endl);
 
-    update_length(d.c_size);
+    update_length();
+
+    d.use_sdim_for_slice = false;
+}
+
+void
+Array::add_constraint(Dim_iter i, D4Dimension *dim)
+{
+    dimension &d = *i ;
+
+    if (dim->constrained())
+    	add_constraint(i, dim->c_start(), dim->c_stride(), dim->c_stop());
+
+    dim->set_used_by_projected_var(true);
+
+	// In this case the value below overrides the value for use_sdim_for_slice
+	// set in the above call. jhrg 12/20/13
+	d.use_sdim_for_slice = true;
 }
 
 /** Returns an iterator to the first dimension of the Array. */
@@ -400,6 +513,8 @@ Array::dim_end()
     return _shape.end() ;
 }
 
+//TODO Many of these methods take a bool parameter that serves no use; remove.
+
 /** 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.
@@ -408,21 +523,10 @@ Array::dim_end()
     @param constrained A boolean flag to indicate whether the array is
     constrained or not.  Ignored.
 */
-
 unsigned int
 Array::dimensions(bool /*constrained*/)
 {
-#if 0
-	// TODO This could be _shape.end() - _shape.begin()
-    unsigned int dim = 0;
-    for (Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
-        dim++;
-    }
-
-    return dim;
-#endif
-
-    return _shape.end() - _shape.begin();
+    return _shape.size();
 }
 
 /** Return the size of the array dimension referred to by <i>i</i>.
@@ -554,13 +658,27 @@ Array::dimension_name(Dim_iter i)
     return (*i).name;
 }
 
+D4Dimension *
+Array::dimension_D4dim(Dim_iter i)
+{
+	return (!_shape.empty()) ? (*i).dim : 0;
+}
+
+D4Maps *
+Array::maps()
+{
+	if (!d_maps) d_maps = new D4Maps(this); 	// init with this as parent
+	return d_maps;
+}
+
+#if 0
 /**
  * @brief Returns the width of the data, in bytes.
  * @param constrained if true, return the size of the array in bytes taking into
  * account the current constraints on various dimensions. False by default.
  * @return The number of bytes needed to store the array values.
  */
-unsigned int Array::width(bool constrained)
+unsigned int Array::width(bool constrained) const
 {
 
 	if (constrained) {
@@ -577,6 +695,120 @@ unsigned int Array::width(bool constrained)
 		return length * var()->width(false);
 	}
 }
+#endif
+
+class PrintD4ArrayDimXMLWriter: public unary_function<Array::dimension&, void> {
+	XMLWriter &xml;
+	// Was this variable constrained using local/direct slicing? i.e., is d_local_constraint set?
+	// If so, don't use shared dimensions; instead emit Dim elements that are anonymous.
+	bool d_constrained;
+public:
+
+	PrintD4ArrayDimXMLWriter(XMLWriter &xml, bool c) : xml(xml), d_constrained(c) { }
+
+	void operator()(Array::dimension &d)
+	{
+		// This duplicates code in D4Dimensions (where D4Dimension::print_dap4() is defined
+		// because of the need to print the constrained size of a dimension. I think that
+		// the constraint information has to be kept here and not in the dimension (since they
+		// are shared dims). Could hack print_dap4() to take the constrained size, however.
+		if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Dim") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Dim element");
+
+		string name = (d.dim) ? d.dim->fully_qualified_name() : d.name;
+		// If there is a name, there must be a Dimension (named dimension) in scope
+		// so write its name but not its size.
+		if (!d_constrained && !name.empty()) {
+			if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*) name.c_str())
+					< 0) throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+		}
+		else if (d.use_sdim_for_slice) {
+			assert(!name.empty());
+			if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*) name.c_str())
+					< 0) throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+		}
+		else {
+			ostringstream size;
+			size << (d_constrained ? d.c_size : d.size);
+			if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "size",
+					(const xmlChar*) size.str().c_str()) < 0)
+				throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+		}
+
+		if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not end Dim element");
+	}
+};
+
+class PrintD4ConstructorVarXMLWriter: public unary_function<BaseType*, void> {
+	XMLWriter &xml;
+	bool d_constrained;
+public:
+	PrintD4ConstructorVarXMLWriter(XMLWriter &xml, bool c) : xml(xml), d_constrained(c) { }
+
+	void operator()(BaseType *btp)
+	{
+		btp->print_dap4(xml, d_constrained);
+	}
+};
+
+class PrintD4MapXMLWriter: public unary_function<D4Map*, void> {
+	XMLWriter &xml;
+
+public:
+	PrintD4MapXMLWriter(XMLWriter &xml) : xml(xml) { }
+
+	void operator()(D4Map *m)
+	{
+		m->print_dap4(xml);
+	}
+};
+
+/**
+ * @brief Print the DAP4 representation of an array.
+ * @param xml
+ * @param constrained
+ */
+void
+Array::print_dap4(XMLWriter &xml, bool constrained /* default: false*/)
+{
+	if (constrained && !send_p()) return;
+
+	if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) var()->type_name().c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
+
+	if (!name().empty())
+		if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+
+	// Hack job... Copied from D4Enum::print_xml_writer. jhrg 11/12/13
+	if (var()->type() == dods_enum_c) {
+		D4Enum *e = static_cast<D4Enum*>(var());
+		string path = e->enumeration()->name();
+		if (e->enumeration()->parent()) {
+			// print the FQN for the enum def; D4Group::FQN() includes the trailing '/'
+			path = static_cast<D4Group*>(e->enumeration()->parent()->parent())->FQN() + path;
+		}
+		if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "enum", (const xmlChar*)path.c_str()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write attribute for enum");
+	}
+
+	if (prototype()->is_constructor_type()) {
+		Constructor &c = static_cast<Constructor&>(*prototype());
+		for_each(c.var_begin(), c.var_end(), PrintD4ConstructorVarXMLWriter(xml, constrained));
+		// bind2nd(mem_fun_ref(&BaseType::print_dap4), xml));
+	}
+
+	// Drop the local_constraint which is per-array and use a per-dimension on instead
+    for_each(dim_begin(), dim_end(), PrintD4ArrayDimXMLWriter(xml, constrained));
+
+	attributes()->print_dap4(xml);
+
+	for_each(maps()->map_begin(), maps()->map_end(), PrintD4MapXMLWriter(xml));
+
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
+}
 
 /** Prints a declaration for the Array.  This is what appears in a
     DDS.  If the Array is constrained, the declaration will reflect
@@ -813,38 +1045,36 @@ Array::print_array(FILE *out, unsigned int index, unsigned int dims,
 
     @brief Print the value given the current constraint.
 */
-unsigned int
-Array::print_array(ostream &out, unsigned int index, unsigned int dims,
-                   unsigned int shape[])
+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 << "}" ;
+	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;
+	}
+	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;
-    }
+		return index;
+	}
 }
 
 void
diff --git a/Array.h b/Array.h
index 801ccb7..b48e720 100644
--- a/Array.h
+++ b/Array.h
@@ -48,12 +48,15 @@
 #include "Vector.h"
 #endif
 
-#ifndef XMLWRITER_H_
-#include "XMLWriter.h"
-#endif
+//#include "D4Dimensions.h"
 
 namespace libdap
 {
+class D4Group;
+class D4Maps;
+class XMLWriter;
+class D4Dimension;
+class D4Dimensions;
 
 const int DODS_MAX_ARRAY = DODS_INT_MAX;
 
@@ -71,6 +74,11 @@ const int DODS_MAX_ARRAY = DODS_INT_MAX;
     are crucial to its structure. The dimension names correspond to \e Map
     vectors, holding the actual values for that column of the array.
 
+    In DAP4, the Array may be a Coverage or a simple Array. In the former case
+    the Array will have both named dimensions and maps, where the maps (instances
+    of D4Map) are what make the Array a Coverage. Coverages are a generalization
+    of DAP2 Grids.
+
     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
@@ -94,6 +102,7 @@ const int DODS_MAX_ARRAY = DODS_INT_MAX;
     \endverbatim
 
     @note Arrays use zero-based indexing.
+    @note This class is used for both DAP2 and DAP4.
 
     @brief A multidimensional array of identical data types.
     @see Grid
@@ -115,18 +124,70 @@ public:
         typedefs. */
     struct dimension
     {
+    	// In DAP2, the name and size of a dimension is stored here, along
+    	// with information about any constraint. In DAP4, either the name
+    	// and size are stored in the two fields below _or_ the name and
+    	// size information comes from a dimension object defined in a
+    	// group that is referenced by the 'dim' pointer. Do not free this
+    	// pointer; it is shared between the array and the Group where the
+    	// Dimension is defined. To keep Array manageable to implement, size
+    	// will be set here using the value from 'dim' if it is not null.
         int size;  ///< The unconstrained dimension size.
         string name;    ///< The name of this dimension.
+
+        D4Dimension *dim; ///< If not null, a weak pointer to the D4Dimension
+
+        // when a DMR is printed for a data response, if an array uses shared
+        // dimensions and those sdims have been sliced, make sure to use those
+        // and get the syntax correct. That's what this field does - in every
+        // case the array records the sizes of its dimensions and their slices
+        // regardless of whether they were provided explicitly in a CE or inherited
+        // from a sliced sdim.
+        bool use_sdim_for_slice; ///< Used to control printing the DMR in data responses
+
         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
+
+        dimension() : size(0), name(""), dim(0), use_sdim_for_slice(false) {
+            // this information changes with each constraint expression
+            start = 0;
+            stop = 0;
+            stride = 1;
+            c_size = size;
+        }
+
+        dimension(unsigned long s, string n) : size(s), name(n), dim(0), use_sdim_for_slice(false) {
+            start = 0;
+            stop = size - 1;
+            stride = 1;
+            c_size = size;
+        }
+
+        dimension(D4Dimension *d);
+#if 0
+        dimension(D4Dimension *d) : dim(d), use_sdim_for_slice(true) {
+        	size = d->size();
+        	name = d->name();
+
+            start = 0;
+            stop = size - 1;
+            stride = 1;
+            c_size = size;
+        }
+#endif
     };
 
+    D4Maps *d_maps;
+
 private:
     std::vector<dimension> _shape; // list of dimensions (i.e., the shape)
 
+    void update_dimension_pointers(D4Dimensions *old_dims, D4Dimensions *new_dims);
+
     friend class ArrayTest;
+    friend class D4Group;
 
 protected:
     void _duplicate(const Array &a);
@@ -152,28 +213,32 @@ public:
         @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 string &n, BaseType *v, bool is_dap4 = false);
+    Array(const string &n, const string &d, BaseType *v, bool is_dap4 = false);
     Array(const Array &rhs);
     virtual ~Array();
 
     Array &operator=(const Array &rhs);
     virtual BaseType *ptr_duplicate();
 
+    virtual BaseType *transform_to_dap4(D4Group *root, Constructor *container);
+
     void add_var(BaseType *v, Part p = nil);
     void add_var_nocopy(BaseType *v, Part p = nil);
 
-    void append_dim(int size, string name = "");
+    void append_dim(int size, const string &name = "");
+    void append_dim(D4Dimension *dim);
     void prepend_dim(int size, const string& name = "");
+    void prepend_dim(D4Dimension *dim);
     void clear_all_dims();
 
     virtual void add_constraint(Dim_iter i, int start, int stride, int stop);
+    virtual void add_constraint(Dim_iter i, D4Dimension *dim);
     virtual void reset_constraint();
 
-    virtual void clear_constraint();
+    virtual void clear_constraint(); // deprecated
 
-    virtual void update_length(int size);
-    virtual unsigned int width(bool constrained = false);
+    virtual void update_length(int size = 0); // should be used internally only
 
     Dim_iter dim_begin() ;
     Dim_iter dim_end() ;
@@ -183,9 +248,16 @@ public:
     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 D4Dimension *dimension_D4dim(Dim_iter i);
 
     virtual unsigned int dimensions(bool constrained = false);
 
+    virtual D4Maps *maps();
+
+    virtual void print_dap4(XMLWriter &xml, bool constrained = false);
+
+    // These are all DAP2 output methods
+
     virtual void print_decl(ostream &out, string space = "    ",
                             bool print_semi = true,
                             bool constraint_info = false,
diff --git a/AttrTable.cc b/AttrTable.cc
index 4695cce..92abf38 100644
--- a/AttrTable.cc
+++ b/AttrTable.cc
@@ -32,11 +32,6 @@
 
 #include "config.h"
 
-//#define DODS_DEBUG
-
-static char rcsid[]not_used =
-"$Id: AttrTable.cc 27197 2013-10-01 21:29:54Z jimg $";
-
 #include <cassert>
 #include <sstream>
 
@@ -50,6 +45,9 @@ static char rcsid[]not_used =
 // Should the www2id and id2www functions be used to encode attribute names?
 // Probably not... jhrg 11/16/11
 #define WWW_ENCODING 0
+// See the note for del_attr_table(). That method now deletes the contained
+// AttrTable.
+#define NEW_DEL_ATTR_TABLE_BEHAVIOR 0
 
 using std::cerr;
 using std::string;
@@ -203,16 +201,13 @@ 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 &
@@ -450,10 +445,9 @@ AttrTable::append_container(AttrTable *at, const string &name)
 #endif
 
     if (simple_find(name) != attr_end())
-        throw Error(
-                string("There already exists a container called `") + name + string("' in this attribute table. (1)"));
-    DBG(cerr << "Setting appended attribute container name to: "
-            << lname << endl);
+        throw Error("There already exists a container called '" + name + "' in this attribute table (" + at->get_name() + "). (1)");
+
+    DBG(cerr << "Setting appended attribute container name to: " << lname << endl);
     at->set_name(lname);
 
     entry *e = new entry;
@@ -770,6 +764,16 @@ AttrTable::get_attr_table(Attr_iter iter)
  The caller will gain control of the AttrTable* located at
  get_attr_table(iter) prior to this call.
 
+ @note The original semantics of this methods were odd. The caller was
+ responsible for deleting the AttrTable, but if they did that before calling
+ this, then memory corruption would happen (because this code accesses a
+ field of the table). If the caller did not delete the table, memory leaked.
+ The only correct way to call the method was to grab the pointer, call this
+ and then delete the pointer. I added a call to delete the contained
+ AttrTable pointer, which changes the behavior of this, but probably in a
+ way that will fix leaks in existing code. This change can be reverted by
+ setting NEW_DEL_ATTR_TABLE_BEHAVIOR to false. jhrg 4/26/13
+
  @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 */
@@ -781,12 +785,17 @@ AttrTable::Attr_iter AttrTable::del_attr_table(Attr_iter 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;
+    struct entry *e = *iter;
     // container no longer has a parent.
     if (e->attributes) {
         e->attributes->d_parent = 0;
+
+#if NEW_DEL_ATTR_TABLE_BEHAVIOR
+        delete e->attributes;
+#endif
+        e->attributes = 0;
     }
-    e->attributes = 0;
+
     delete e;
 
     return attr_map.erase(iter);
@@ -1479,6 +1488,17 @@ void AttrTable::print_xml_writer(XMLWriter &xml)
     }
 }
 
+/** Write the DAP4 XML representation for this attribute table. This
+ * method is used to build the DAP4 DMR response object.
+ *
+ * @param xml An XMLWriter that will do the serialization
+ */
+void
+AttrTable::print_dap4(XMLWriter &xml)
+{
+    print_xml_writer(xml);
+}
+
 /** @brief dumps information about this object
  *
  * Displays the pointer value of this instance and all attributes stored
diff --git a/AttrTable.h b/AttrTable.h
index 69b2f0d..d83db9b 100644
--- a/AttrTable.h
+++ b/AttrTable.h
@@ -134,15 +134,7 @@ AttrType String_to_AttrType(const string &s);
     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
+	@note This class is used only for DAP2.
 
     @brief Contains the attributes for a dataset.
     @see DAS
@@ -344,6 +336,8 @@ public:
 
     void print_xml_writer(XMLWriter &xml);
 
+    void print_dap4(XMLWriter &xml);
+
     virtual void dump(ostream &strm) const ;
 };
 
diff --git a/BaseType.cc b/BaseType.cc
index 6dcce06..cfe0236 100644
--- a/BaseType.cc
+++ b/BaseType.cc
@@ -57,6 +57,11 @@
 #include "Sequence.h"
 #include "Grid.h"
 
+#include "D4Attributes.h"
+#include "DMR.h"
+#include "XMLWriter.h"
+#include "D4BaseTypeFactory.h"
+
 #include "InternalErr.h"
 
 #include "util.h"
@@ -79,8 +84,8 @@ namespace libdap {
 void
 BaseType::m_duplicate(const BaseType &bt)
 {
-    DBG2(cerr << "BaseType::_duplicate: " << bt.d_name << " send_p: "
-            << bt.d_is_send << endl);
+    DBG(cerr << "In BaseType::m_duplicate for " << bt.name() << endl);
+
     d_name = bt.d_name;
     d_type = bt.d_type;
     d_dataset = bt.d_dataset;
@@ -93,11 +98,14 @@ BaseType::m_duplicate(const BaseType &bt)
 
     d_attr = bt.d_attr;  // Deep copy.
 
-#if DAP4
-    // FIXME How to copy? these are pointers
-    d_dims = bt.d_dims;
-    d_maps = bt.d_maps;
-#endif
+    if (bt.d_attributes)
+        d_attributes = new D4Attributes(*bt.d_attributes); // deep copy
+    else
+        d_attributes = 0; // init to null if not used.
+
+    d_is_dap4 = bt.d_is_dap4;
+
+    DBG(cerr << "Exiting BaseType::m_duplicate for " << bt.name() << endl);
 }
 
 // Public mfuncs
@@ -116,8 +124,8 @@ BaseType::m_duplicate(const BaseType &bt)
     @see Type */
 BaseType::BaseType(const string &n, const Type &t, bool is_dap4)
         : d_name(n), d_type(t), d_dataset(""), d_is_read(false), d_is_send(false),
-        d_in_selection(false), d_is_synthesized(false), d_parent(0),
-        d_is_dap4(is_dap4)
+        d_parent(0), d_attributes(0), d_is_dap4(is_dap4),
+        d_in_selection(false), d_is_synthesized(false)
 {}
 
 /** The BaseType constructor needs a name, a dataset, and a type.
@@ -134,66 +142,37 @@ BaseType::BaseType(const string &n, const Type &t, bool is_dap4)
     @see Type */
 BaseType::BaseType(const string &n, const string &d, const Type &t, bool is_dap4)
         : d_name(n), d_type(t), d_dataset(d), d_is_read(false), d_is_send(false),
-        d_in_selection(false), d_is_synthesized(false), d_parent(0),
-        d_is_dap4(is_dap4)
-{}
-#if 0
-/** 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, bool is_dap4)
-        : d_name(n), d_type(t), d_dataset(""), d_is_read(false), d_is_send(false),
-        d_in_selection(false), d_is_synthesized(false), d_parent(0),
-        d_is_dap4(is_dap4)
+        d_parent(0), d_attributes(0), d_is_dap4(is_dap4),
+        d_in_selection(false), d_is_synthesized(false)
 {}
 
-/** 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, bool is_dap4)
-        : d_name(n), d_type(t), d_dataset(d), d_is_read(false), d_is_send(false),
-        d_in_selection(false), d_is_synthesized(false), d_parent(0),
-        d_is_dap4(is_dap4)
-{}
-#endif
 /** @brief The BaseType copy constructor. */
 BaseType::BaseType(const BaseType &copy_from) : DapObj()
 {
+    DBG(cerr << "In BaseTpe::copy_ctor for " << copy_from.name() << endl);
     m_duplicate(copy_from);
 }
 
 BaseType::~BaseType()
 {
     DBG2(cerr << "Entering ~BaseType (" << this << ")" << endl);
+
+    if (d_attributes)
+        delete d_attributes;
+
     DBG2(cerr << "Exiting ~BaseType" << endl);
 }
 
 BaseType &
 BaseType::operator=(const BaseType &rhs)
 {
+    DBG(cerr << "Entering BaseType::operator=" << endl);
     if (this == &rhs)
         return *this;
 
     m_duplicate(rhs);
 
+    DBG(cerr << "Exiting BaseType::operator=" << endl);
     return *this;
 }
 
@@ -218,6 +197,34 @@ BaseType::toString()
     return oss.str();
 }
 
+/** @brief DAP2 to DAP4 transform
+ *
+ * For the current BaseType, return a DAP4 'copy' of the variable.
+ *
+ * @note For most DAP2 types, in this implementation of DAP4 the corresponding
+ * DAP4 type is the same. The different types are Sequences (which are D4Sequences
+ * in the DAP4 implementation), Grids (which are coverages) and Arrays (which use
+ * shared dimensions).
+ *
+ * @param root The root group that should hold this new variable. Add Group-level
+ * stuff here (e.g., D4Dimensions).
+ * @param container Add the new variable to this container.
+ *
+ * @return A pointer to the transformed variable
+ */
+BaseType *
+BaseType::transform_to_dap4(D4Group */*root*/, Constructor */*container*/)
+{
+	BaseType *dest = ptr_duplicate();
+
+	// Copy the D2 attributes from 'this' to dest's D4 Attributes
+	dest->attributes()->transform_to_dap4(get_attr_table());
+
+	dest->set_is_dap4(true);
+
+	return dest;
+}
+
 /** @brief dumps information about this object
  *
  * Displays the pointer value of this instance and then displays information
@@ -256,6 +263,23 @@ BaseType::name() const
     return d_name;
 }
 
+/**
+ * Return the FQN for this variable. This will include the D4 Group
+ * component of the name.
+ *
+ * @return The FQN in a string
+ */
+string
+BaseType::FQN() const
+{
+	if (get_parent() == 0)
+		return name();
+	else if (get_parent()->type() == dods_group_c)
+		return get_parent()->FQN() + name();
+	else
+		return get_parent()->FQN() + "." + name();
+}
+
 /** @brief Sets the name of the class instance. */
 void
 BaseType::set_name(const string &n)
@@ -295,58 +319,10 @@ BaseType::set_type(const Type &t)
 string
 BaseType::type_name() const
 {
-    return libdap::type_name(d_type);
-#if 0
-    switch (d_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");
-
-    case dods_int8_c:
-        return string("Int8");
-    case dods_uint8_c:
-        return string("UInt8");
-    case dods_int64_c:
-        return string("Int64");
-    case dods_uint64_c:
-        return string("UInt64");
-    case dods_url4_c:
-        return string("URL");
-    case dods_group_c:
-        return string("Group");
-    case dods_enum_c:
-        return string("Enum");
-
-    default:
-        cerr << "BaseType::type_name: Undefined type" << endl;
-        return string("");
-    }
-#endif
+	if (is_dap4())
+		return libdap::D4type_name(d_type);
+	else
+		return libdap::D2type_name(d_type);
 }
 
 /** @brief Returns true if the instance is a numeric, string or URL
@@ -355,90 +331,18 @@ BaseType::type_name() const
     False otherwise. Arrays (even of simple types) return False.
     @see is_vector_type() */
 bool
-BaseType::is_simple_type()
+BaseType::is_simple_type() const
 {
     return libdap::is_simple_type(type());
-#if 0
-    switch (type()) {
-    case dods_null_c:
-    case dods_byte_c:
-
-    case dods_int8_c:
-    case dods_uint8_c:
-
-    case dods_int16_c:
-    case dods_uint16_c:
-    case dods_int32_c:
-    case dods_uint32_c:
-
-    case dods_int64_c:
-    case dods_uint64_c:
-
-    case dods_float32_c:
-    case dods_float64_c:
-    case dods_str_c:
-    case dods_url_c:
-
-    case dods_url4_c:
-    case dods_enum_c:
-        return true;
-
-    case dods_array_c:
-    case dods_structure_c:
-    case dods_sequence_c:
-    case dods_grid_c:
-    case dods_group_c:
-        return false;
-    }
-
-    return false;
-#endif
 }
 
 /** @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()
+BaseType::is_vector_type() const
 {
     return libdap::is_vector_type(type());
-#if 0
-    switch (type()) {
-    case dods_null_c:
-    case dods_byte_c:
-
-    case dods_int8_c:
-    case dods_uint8_c:
-
-    case dods_int16_c:
-    case dods_uint16_c:
-    case dods_int32_c:
-    case dods_uint32_c:
-
-    case dods_int64_c:
-    case dods_uint64_c:
-
-    case dods_float32_c:
-    case dods_float64_c:
-    case dods_str_c:
-    case dods_url_c:
-
-    case dods_url4_c:
-    case dods_enum_c:
-        return false;
-
-    case dods_array_c:
-        return true;
-
-    case dods_structure_c:
-    case dods_sequence_c:
-    case dods_grid_c:
-    case dods_group_c:
-        return false;
-    }
-
-    return false;
-#endif
 }
 
 /** @brief Returns true if the instance is a constructor (i.e., Structure,
@@ -446,73 +350,11 @@ BaseType::is_vector_type()
     @return True if the instance is a Structure, Sequence or Grid, False
     otherwise. */
 bool
-BaseType::is_constructor_type()
+BaseType::is_constructor_type() const
 {
     return libdap::is_constructor_type(type());
-#if 0
-    switch (type()) {
-    case dods_null_c:
-    case dods_byte_c:
-
-    case dods_int8_c:
-    case dods_uint8_c:
-
-    case dods_int16_c:
-    case dods_uint16_c:
-    case dods_int32_c:
-    case dods_uint32_c:
-
-    case dods_int64_c:
-    case dods_uint64_c:
-
-    case dods_float32_c:
-    case dods_float64_c:
-    case dods_str_c:
-    case dods_url_c:
-
-    case dods_url4_c:
-    case dods_enum_c:
-
-    case dods_array_c:
-        return false;
-
-    case dods_structure_c:
-    case dods_sequence_c:
-    case dods_grid_c:
-    case dods_group_c:
-        return true;
-    }
-
-    return false;
-#endif
-}
-
-#if 0
-/**
- * Return true if this variable's type is allowed only for DAP4.
- *
- * @note the default implementation returns false; the new DAP4
- * implementations must overload this method.
- */
-bool
-BaseType::is_dap4_only_type()
-{
-    return false;
 }
 
-/**
- * Return true if this variable's type is allowed only for DAP2.
- *
- * @note the default implementation returns false; the old DAP2
- * implementations must overload this method.
- */
-bool
-BaseType::is_dap2_only_type()
-{
-    return false;
-}
-#endif
-
 /** 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
@@ -589,7 +431,7 @@ BaseType::read_p()
     @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_()
+    specialization of Sequence::set_read_p(). By default Sequence::set_read_p()
     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
@@ -597,12 +439,6 @@ BaseType::read_p()
     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
@@ -617,11 +453,21 @@ BaseType::read_p()
 void
 BaseType::set_read_p(bool state)
 {
+    d_is_read = state;
+
+    // The is_synthesized property was not being used and the more I thought
+    // about how this was coded, the more this code below seemed like a bad idea.
+    // Once the property was set, the read_p property could not be changed.
+    // That seems a little silly. Also, I think I need to use this is_synthesized
+    // property for some of the server function code I'm working on for Raytheon,
+    // and I'd like to be able to control the read_p property! jhrg 3/9/15
+#if 0
     if (! d_is_synthesized) {
         DBG2(cerr << "Changing read_p state of " << name() << " to "
 	         << state << endl);
         d_is_read = state;
     }
+#endif
 }
 
 /** Returns the state of the \c send_p property. If true, this variable
@@ -676,6 +522,29 @@ BaseType::set_attr_table(const AttrTable &at)
     d_attr = at;
 }
 
+/** DAP4 Attribute methods
+ * @{
+ */
+D4Attributes *
+BaseType::attributes()
+{
+    if (!d_attributes) d_attributes = new D4Attributes();
+    return d_attributes;
+}
+
+void
+BaseType::set_attributes(D4Attributes *attrs)
+{
+    d_attributes = new D4Attributes(*attrs);
+}
+
+void
+BaseType::set_attributes_nocopy(D4Attributes *attrs)
+{
+    d_attributes = attrs;
+}
+///@}
+
 /**
  * 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
@@ -785,7 +654,7 @@ BaseType::set_parent(BaseType *parent)
 
     @return A BaseType pointer to the variable's parent. */
 BaseType *
-BaseType::get_parent()
+BaseType::get_parent() const
 {
     return d_parent;
 }
@@ -854,6 +723,12 @@ BaseType::add_var(BaseType *, Part)
     throw InternalErr(__FILE__, __LINE__, "BaseType::add_var unimplemented");
 }
 
+void
+BaseType::add_var_nocopy(BaseType *, Part)
+{
+    throw InternalErr(__FILE__, __LINE__, "BaseType::add_var_nocopy 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
@@ -912,18 +787,25 @@ BaseType::add_var(BaseType *, Part)
 
     @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()).
+	@todo Modify the D4 serialize code so that it supports the true/false
+	behavior of read() for arrays.
+
+	@todo Modify all of the stock handlers so they conform to this!
+
+    @return False means more data remains to be read, True indicates that no
+    more data need to be read. For Sequence and D4Sequence, this method will
+    generally read one instance of the Sequence; for other types it will generally
+    read the entire variable modulo any limitations due to a constraint. However,
+    the library should be written so that read can return less than all of the data
+    for a variable - serialize() would then call the function until it returns
+    True.
 
-    @see BaseType
-    @see Sequence  */
+    @see BaseType */
 bool
 BaseType::read()
 {
     if (d_is_read)
-        return false;
+        return true;
 
     throw InternalErr("Unimplemented BaseType::read() method called for the variable named: " + name());
 }
@@ -939,6 +821,44 @@ BaseType::intern_data(ConstraintEvaluator &, DDS &dds)
     dds.timeout_off();
 }
 
+/**
+ * @brief Read data into this variable
+ * @param eval Evaluator for a constraint expression
+ * @param dmr DMR for the whole dataset
+ */
+void
+BaseType::intern_data(Crc32 &checksum/*, DMR &, ConstraintEvaluator &*/)
+{
+    if (!read_p())
+        read();          // read() throws Error and InternalErr
+
+    compute_checksum(checksum);
+}
+
+bool
+BaseType::serialize(ConstraintEvaluator &, DDS &,  Marshaller &, bool)
+{
+	throw InternalErr(__FILE__, __LINE__, "The DAP2 serialize() method has not been implemented for " + type_name());
+}
+
+bool
+BaseType::deserialize(UnMarshaller &, DDS *, bool)
+{
+	throw InternalErr(__FILE__, __LINE__, "The DAP2 deserialize() method has not been implemented for " + type_name());
+}
+
+void
+BaseType::serialize(D4StreamMarshaller &, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+	throw InternalErr(__FILE__, __LINE__, "The DAP4 serialize() method has not been implemented for " + type_name());
+}
+
+void
+BaseType::deserialize(D4StreamUnMarshaller &, DMR &)
+{
+	throw InternalErr(__FILE__, __LINE__, "The DAP4 deserialize() method has not been implemented for " + type_name());
+}
+
 /** 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
@@ -1054,6 +974,28 @@ BaseType::print_decl(ostream &out, string space, bool print_semi,
 	out << ";\n" ;
 }
 
+/** 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.
+
+ at brief Prints the value of the variable.
+
+ at param out The output stream on which to print the value.
+ at param space This value is passed to the print_decl()
+function, and controls the leading spaces of the output.
+ at param print_decl_p A boolean value controlling whether the
+variable declaration is printed as well as the value. */
+void
+BaseType::print_val(FILE *out, string space, bool print_decl_p)
+{
+    ostringstream oss;
+    print_val(oss, space, print_decl_p);
+    fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
+}
+
 /** Write the XML representation of this variable. This method is used to
     build the DDX XML response.
     @param out Destination.
@@ -1103,13 +1045,29 @@ BaseType::print_xml_writer(XMLWriter &xml, bool constrained)
     if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
         throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
 
-    if (get_attr_table().get_size() > 0)
+    if (is_dap4())
+        attributes()->print_dap4(xml);
+
+    if (!is_dap4() && get_attr_table().get_size() > 0)
         get_attr_table().print_xml_writer(xml);
 
     if (xmlTextWriterEndElement(xml.get_writer()) < 0)
         throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
 }
 
+/** Write the DAP4 XML representation for this variable. This method is used
+ * to build the DAP4 DMR response object.
+ *
+ * @param xml An XMLWriter that will do the serialization
+ * @param constrained True if the response should show the variables subject
+ * to the current constraint expression.
+ */
+void
+BaseType::print_dap4(XMLWriter &xml, bool constrained)
+{
+    print_xml_writer(xml, constrained);
+}
+
 // 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
@@ -1204,18 +1162,21 @@ BaseType::ops(BaseType *, int)
     throw InternalErr(__FILE__, __LINE__, "Unimplemented operator.");
 }
 
-// FIXME update this comment if the removal of width() works
-/** This version of width simply returns the same thing as width() for simple
-    types and Arrays. For Constructors, it needs to be specialized. This is
-    partly due to an inconsistency in the way Vector::width() is implemented.
-    That method uses the constrained size of the array (while the Constructor
-    versions do not take the constraint into account).
-
-    @param constrained If true, return the size after applying a constraint.
-    @return  The number of bytes used by the variable.
+/**
+ * @brief How many bytes does this use
+ * Return the number of bytes of storage this variable uses. For scalar types,
+ * this is pretty simple (an int32 uses 4 bytes, etc.). For arrays and Constructors,
+ * it is a bit more complex. Note that a scalar String variable uses sizeof(String*)
+ * bytes, not the length of the string. In other words, the value returned is
+ * independent of the type. Also note width() of a String array returns the number of
+ * elements in the array times sizeof(String*). That is, each different array size
+ * is a different data type.
+ *
+ * @param constrained Should the current constraint be taken into account?
+ * @return Bytes of storage
  */
 unsigned int
-BaseType::width(bool /* constrained */)
+BaseType::width(bool /* constrained */) const
 {
 	throw InternalErr(__FILE__, __LINE__, "not implemented");
 #if 0
diff --git a/BaseType.h b/BaseType.h
index a400887..136e49a 100644
--- a/BaseType.h
+++ b/BaseType.h
@@ -42,127 +42,43 @@
 #ifndef _basetype_h
 #define _basetype_h 1
 
-
 #include <vector>
 #include <stack>
 #include <iostream>
 #include <string>
 
-// These are instantiated only for DAP4 variables
-#if DAP4
-#include "D4Dimensions.h"
-#include "D4Maps.h"
-#endif
-
 #include "AttrTable.h"
 
 #include "InternalErr.h"
 
 #include "dods-datatypes.h"
+#include "Type.h"
 
 #include "DapObj.h"
 
-#include "XMLWriter.h"
-
 using namespace std;
 
+class Crc32;
+
 namespace libdap
 {
 
-class DDS;
 class ConstraintEvaluator;
+
+class DDS;
 class Marshaller;
 class UnMarshaller;
 
-/** <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
-};
+class Constructor;
+class XMLWrter;
 
-/** <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,
-
-    dods_int8_c,
-    dods_uint8_c,
-    dods_int64_c,
-    dods_uint64_c,
-    dods_url4_c
-    dods_enum_c,
-    dods_group_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,
-
-    // Added for DAP4
-    dods_int8_c,
-    dods_uint8_c,
-
-    dods_int64_c,
-    dods_uint64_c,
-
-    dods_url4_c,
-
-    dods_enum_c,
-    dods_group_c
+class DMR;
+class D4Group;
+class XMLWriter;
+class D4StreamMarshaller;
+class D4StreamUnMarshaller;
 
-};
+class D4Attributes;
 
 /** This defines the basic data type features for the DODS data access
     protocol (DAP) data types. All the DAP type classes (Float64, Array,
@@ -174,11 +90,11 @@ enum Type {
     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
+    is called to send data to the client. On the client side, most DAP
     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
+    In order to use these classes on the server side of a DAP
     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
@@ -194,6 +110,8 @@ enum Type {
     the constraints
     to be returned. These cautions are outlined where they occur.
 
+	@note This class is ued by both DAP2 and DAP4.
+
     @brief The basic data type for the DODS DAP types.  */
 
 class BaseType : public DapObj
@@ -205,8 +123,6 @@ private:
 
     bool d_is_read;  // true if the value has been read
     bool d_is_send;  // Is the variable in the projection?
-    bool d_in_selection; // Is the variable in the selection?
-    bool d_is_synthesized; // 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
@@ -216,17 +132,17 @@ private:
     // Attributes for this variable. Added 05/20/03 jhrg
     AttrTable d_attr;
 
+    D4Attributes *d_attributes;
+
     bool d_is_dap4;         // True if this is a DAP4 variable, false ... DAP2
 
     // These are non-empty only for DAP4 variables. Added 9/27/12 jhrg
 
-    // FIXME Remove this. This header cannot have compile-time variation
-#if DAP4
-    D4Dimensions d_dims;   // If non-empty, this BaseType is an DAP4 Array
-    D4Maps d_maps;         // if non-empty, this BaseType is a DAP4 'Grid'
-#endif
-
 protected:
+    // These were/are used for DAP2 CEs, but not for DAP4 ones
+    bool d_in_selection; // Is the variable in the selection?
+    bool d_is_synthesized; // true if the variable is synthesized
+
     void m_duplicate(const BaseType &bt);
 
 public:
@@ -235,21 +151,19 @@ public:
     // These ctors assume is_dap4 is false
     BaseType(const string &n, const Type &t, bool is_dap4 = false);
     BaseType(const string &n, const string &d, const Type &t, bool is_dap4 = false);
-#if 0
-    // These provide a way to set is_dap4
-    BaseType(const string &n, const Type &t, bool is_dap4);
-    BaseType(const string &n, const string &d, const Type &t, bool is_dap4);
-#endif
+
     BaseType(const BaseType &copy_from);
     virtual ~BaseType();
 
     virtual string toString();
 
+    virtual BaseType *transform_to_dap4(D4Group *root, Constructor *container);
+
     virtual void dump(ostream &strm) const ;
 
     BaseType &operator=(const BaseType &rhs);
 
-    bool is_dap4() { return d_is_dap4; }
+    bool is_dap4() const { return d_is_dap4; }
     void set_is_dap4(const bool v) { d_is_dap4 = v;}
 
     /** Clone this instance. Allocate a new instance and copy \c *this into
@@ -262,6 +176,7 @@ public:
 
     string name() const;
     virtual void set_name(const string &n);
+    virtual std::string FQN() const;
 
     Type type() const;
     void set_type(const Type &t);
@@ -269,15 +184,24 @@ public:
 
     string dataset() const ;
 
-    virtual bool is_simple_type();
-    virtual bool is_vector_type();
-    virtual bool is_constructor_type();
+    /**
+     * @brief How many elements are in this variable.
+     * @todo change the return type to int64_t
+     * @return The number of elements; 1 for scalars
+     */
+    virtual int length() const { return 1; }
+
+    /**
+     * @brief Set the number of elements for this variable
+     * @todo change param type to int64_t
+     * @param l The number of elements
+     */
+    virtual void set_length(int) { }
+
+    virtual bool is_simple_type() const;
+    virtual bool is_vector_type() const;
+    virtual bool is_constructor_type() const;
 
-#if 0
-    // Not yet, if ever. Allow 'sloppy' changeover in the handlers
-    virtual bool is_dap4_only_type();
-    virtual bool is_dap2_only_type();
-#endif
     virtual bool synthesized_p();
     virtual void set_synthesized_p(bool state);
 
@@ -292,11 +216,16 @@ public:
     virtual AttrTable &get_attr_table();
     virtual void set_attr_table(const AttrTable &at);
 
+    // DAP4 attributes
+    virtual D4Attributes *attributes();
+    virtual void set_attributes(D4Attributes *);
+    virtual void set_attributes_nocopy(D4Attributes *);
+
     virtual bool is_in_selection();
     virtual void set_in_selection(bool state);
 
     virtual void set_parent(BaseType *parent);
-    virtual BaseType *get_parent();
+    virtual BaseType *get_parent() const;
 
     virtual void transfer_attributes(AttrTable *at);
 
@@ -338,6 +267,7 @@ public:
     virtual BaseType *var(const string &name, btp_stack &s);
 
     virtual void add_var(BaseType *bt, Part part = nil);
+    virtual void add_var_nocopy(BaseType *bt, Part part = nil);
 
     virtual bool read();
 
@@ -345,6 +275,8 @@ public:
 
     virtual bool ops(BaseType *b, int op);
 
+    virtual unsigned int width(bool constrained = false) const;
+
     virtual void print_decl(FILE *out, string space = "    ",
                             bool print_semi = true,
                             bool constraint_info = false,
@@ -363,6 +295,8 @@ public:
 
     virtual void print_xml_writer(XMLWriter &xml, bool constrained = false);
 
+    virtual void print_dap4(XMLWriter &xml, bool constrained = false);
+
     /** @name Abstract Methods */
     //@{
 #if 0
@@ -379,8 +313,6 @@ public:
 	@brief Returns the size of the class instance data. */
     virtual unsigned int width(bool constrained = false) = 0;
 #endif
-    virtual unsigned int width(bool constrained = false);
-
     /** 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>
@@ -475,8 +407,30 @@ public:
 	@exception InternalErr.
 	@exception Error.
 	@see DDS */
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true) = 0;
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,  Marshaller &m, bool ce_eval = true);
+
+    /**
+     * @brief include the data for this variable in the checksum
+     * DAP4 includes a checksum with every data response. This method adds the
+     * variable's data to that checksum.
+     * @param checksum A Crc32 instance that holds the current checksum.
+     */
+    virtual void compute_checksum(Crc32 &checksum) = 0;
+
+    virtual void intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator &eval*/);
+
+    /**
+     * @brief The DAP4 serialization method.
+     * Serialize a variable's values for DAP4. This does not write the DMR
+     * persistent representation but does write that part of the binary
+     * data blob that holds a variable's data.
+     * @param m
+     * @param dmr
+     * @param eval
+     * @param filter True if there is one variable that should be 'filtered'
+     * @exception Error or InternalErr
+     */
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
 
     /** Receives data from the network connection identified by the
 	<tt>source</tt> parameter. The data is put into the class data
@@ -502,7 +456,15 @@ public:
 	@exception Error when a problem reading from the UnMarshaller is
 	found.
 	@see DDS */
-    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false) = 0;
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    /**
+     * The DAP4 deserialization method.
+     * @param um
+     * @param dmr
+     * @exception Error or InternalErr
+     */
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
 
     /** Prints the value of the variable, with its declaration. This
 	function is primarily intended for debugging DODS
@@ -520,7 +482,7 @@ public:
 	variable declaration is printed as well as the value. */
 
     virtual void print_val(FILE *out, string space = "",
-                           bool print_decl_p = true) = 0;
+                           bool print_decl_p = true);
 
     /** Prints the value of the variable, with its declaration. This
 	function is primarily intended for debugging DODS
diff --git a/BaseTypeFactory.cc b/BaseTypeFactory.cc
index 0e2639a..fa9c4fd 100644
--- a/BaseTypeFactory.cc
+++ b/BaseTypeFactory.cc
@@ -23,6 +23,7 @@
 //
 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
+#include "config.h"
 
 #include <string>
 
@@ -78,9 +79,10 @@ BaseTypeFactory::NewVariable(Type type, const string &name) const
 	case dods_grid_c:
 		return NewGrid(name);
 	default:
-		throw InternalErr(__FILE__, __LINE__, "Unknow type");
+		throw InternalErr(__FILE__, __LINE__, "Unknown type");
 	}
 }
+
 Byte *
 BaseTypeFactory::NewByte(const string &n) const
 {
diff --git a/BaseTypeFactory.h b/BaseTypeFactory.h
index 408e557..85a02b7 100644
--- a/BaseTypeFactory.h
+++ b/BaseTypeFactory.h
@@ -28,6 +28,9 @@
 
 #include <string>
 
+#include "Type.h"
+#include "InternalErr.h"
+
 // Class declarations; Make sure to include the corresponding headers in the
 // implementation file.
 
@@ -82,7 +85,25 @@ public:
     virtual ~BaseTypeFactory()
     {}
 
-    virtual BaseType *NewVariable(Type type, const string &name = "") const;
+    /**
+     * Build a new variable and return it using a BaseType pointer. The
+     * type of the variable is given using  Type enumeration.
+     *
+     * @note Added for DAP4
+     *
+     * @param t The type of the variable to create
+     * @parma name The (optional) name of the variable.
+     */
+    virtual BaseType *NewVariable(Type t, const string &name = "") const;
+
+    /**
+     * Clone this object and return a pointer to the clone.
+     *
+     * @note added for DAP4
+     */
+    virtual BaseTypeFactory *ptr_duplicate() const {
+        throw InternalErr(__FILE__, __LINE__, "Not Implemented.");
+    }
 
     virtual Byte *NewByte(const string &n = "") const;
     virtual Int16 *NewInt16(const string &n = "") const;
diff --git a/Byte.cc b/Byte.cc
index 07090c5..c26b425 100644
--- a/Byte.cc
+++ b/Byte.cc
@@ -56,6 +56,10 @@
 #include "Marshaller.h"
 #include "UnMarshaller.h"
 
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
 #include "util.h"
 #include "parser.h"
 #include "dods-limits.h"
@@ -113,7 +117,7 @@ Byte & Byte::operator=(const Byte & rhs)
     return *this;
 }
 
-unsigned int Byte::width(bool)
+unsigned int Byte::width(bool) const
 {
     return sizeof(dods_byte);
 }
@@ -128,18 +132,15 @@ unsigned int Byte::width(bool)
     @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)
+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();
 
@@ -158,6 +159,35 @@ bool Byte::deserialize(UnMarshaller &um, DDS *, bool)
     return false;
 }
 
+void
+Byte::compute_checksum(Crc32 &checksum)
+{
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
+
+/**
+ * @brief Serialize a Byte
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+Byte::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+    m.put_byte( d_buf ) ;
+}
+
+void
+Byte::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+    um.get_byte( d_buf ) ;
+}
+
 /** 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.
diff --git a/Byte.h b/Byte.h
index 345452e..f0a0d0f 100644
--- a/Byte.h
+++ b/Byte.h
@@ -36,7 +36,6 @@
 #ifndef _byte_h
 #define _byte_h 1
 
-
 #ifndef _dods_datatypes_h
 #include "dods-datatypes.h"
 #endif
@@ -74,12 +73,18 @@ public:
 
     Byte &operator=(const Byte &rhs);
 
-    virtual unsigned int width(bool constrained = false);
+    virtual unsigned int width(bool constrained = false) const;
 
     virtual BaseType *ptr_duplicate();
 
-    bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval);
-    bool deserialize(UnMarshaller &um, DDS *, bool);
+    // DAP2
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval);
+    virtual bool deserialize(UnMarshaller &um, DDS *, bool);
+
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
 
     virtual unsigned int val2buf(void *val, bool reuse = false);
     virtual unsigned int buf2val(void **val);
diff --git a/COPYRIGHT_URI b/COPYRIGHT_URI
index 7580200..a368e51 100644
--- a/COPYRIGHT_URI
+++ b/COPYRIGHT_URI
@@ -1,5 +1,5 @@
 
-  $Id: COPYRIGHT_URI 11906 2005-08-08 19:51:43Z root $
+  $Id$
 
   (c) Copyright 1994-2000 by
   The University of Rhode Island and The Massachusetts Institute of Technology
diff --git a/ChangeLog b/ChangeLog
index 490f755..96176f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,385 @@
+2014-08-08  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a leak in RValue.cc using a patch from Aron (ADB)
+
+2014-08-01  James Gallagher <jgallagher at opendap.org>
+
+	Release checklist steps for 3.13.2
+
+	M    ChangeLog
+	M    INSTALL
+	M    NEWS
+	M    README
+	M    configure.ac
+	M    doxy.conf
+	M    libdap.spec
+	M    main_page.doxygen
+
+2014-08-01  James Gallagher <jgallagher at opendap.org>
+
+	Release checklist steps for 3.13.2
+
+	M    ChangeLog
+	M    INSTALL
+	M    NEWS
+	M    README
+	M    configure.ac
+	M    doxy.conf
+	M    libdap.spec
+	M    main_page.doxygen
+
+2014-07-30  James Gallagher <jgallagher at opendap.org>
+
+	Second fix for ticket 2240 - SCAN_STR from the CE scanner
+	was leaking because the parser did not delete the reutrned
+	string. I also modified the first fix so that a local tmp
+	string was used instead of new dynamic storage.
+
+	M    ce_expr.yy
+
+2014-07-30  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a memory leak reported by Aron.Bartle at mechdyne.com. See ticket
+	2240.
+
+	M    ce_expr.yy
+
+2014-07-30  James Gallagher <jgallagher at opendap.org>
+
+	I added a comment about a potential memory leak to ce_expr.yy
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+2014-07-30  James Gallagher <jgallagher at opendap.org>
+
+	Second fix for ticket 2240 - SCAN_STR from the CE scanner
+	was leaking because the parser did not delete the reutrned
+	string. I also modified the first fix so that a local tmp
+	string was used instead of new dynamic storage.
+
+	M    ce_expr.yy
+
+2014-07-30  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a memory leak reported by Aron.Bartle at mechdyne.com. See ticket
+	2240.
+
+	M    ce_expr.yy
+
+2014-07-30  James Gallagher <jgallagher at opendap.org>
+
+	I added a comment about a potential memory leak to ce_expr.yy
+
+2014-05-07  James Gallagher <jgallagher at opendap.org>
+
+	spelling
+
+2014-05-07  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a test baseline in HTTPConnectTest so that it will work with
+	the new headers returned by H 1.9.3 (which include so things from
+	DAP4).
+
+2014-05-05  James Gallagher <jgallagher at opendap.org>
+
+	namespace libdap addex
+
+	M    XMLWriter.h
+
+2014-05-02  James Gallagher <jgallagher at opendap.org>
+
+	Minor edit to Makefile.am for builds on centos 5 - there libgl
+	builds a copy of unistd.h that doesn't work with flex generated cc
+	files. So I pulled -I./gl from CPP flags for the parsers library.
+
+2014-04-22  James Gallagher <jgallagher at opendap.org>
+
+	Updated for 3.13
+
+	M    INSTALL
+	M    README
+	M    configure.ac
+
+2014-04-15  James Gallagher <jgallagher at opendap.org>
+
+	Updates to NEWS, ChangeLog to match the bump in the vesion number.
+
+2014-04-11  James Gallagher <jgallagher at opendap.org>
+
+	Added comment info to abi_checker.xml.in so we'll remember how to use the abi checker.
+
+2014-04-11  James Gallagher <jgallagher at opendap.org>
+
+	path fix/typo
+
+2014-04-11  James Gallagher <jgallagher at opendap.org>
+
+	Added abi_checker.xml.in file for the perl-based abi checker. Seems to work only with gcc.
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+2014-04-11  James Gallagher <jgallagher at opendap.org>
+
+	Added comment info to abi_checker.xml.in so we'll remember how to use the abi checker.
+
+2014-04-11  James Gallagher <jgallagher at opendap.org>
+
+	path fix/typo
+
+2014-04-11  James Gallagher <jgallagher at opendap.org>
+
+	Added abi_checker.xml.in file for the perl-based abi checker. Seems to work only with gcc.
+
+2014-03-26  James Gallagher <jgallagher at opendap.org>
+
+2014-02-05  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the SequenceTest 'baseline' regex.
+
+	M    unit-tests/SequenceTest.cc
+
+2014-02-04  James Gallagher <jgallagher at opendap.org>
+
+	Unit test updates after the OS upgrade from OSX 10.8 to 10.9.
+	There seems to be an issue with the sizeof(std::string) and also
+	with libxml2 and/or my code to read from a C++ stream and have
+	libxml2 parse text/xml. For now I'm removing these tests... but
+	will return to the libxml2 issue later (the sizeof(std::string)
+	maybe a bad idea since that could be pretty variable between
+	libstdc++ versions - I might just drop that test).
+
+2013-11-05  James Gallagher <jgallagher at opendap.org>
+
+	Minor formatting changes
+
+2013-10-24  James Gallagher <jgallagher at opendap.org>
+
+	All tests now pass for array projections for server function
+	arguments.
+
+2013-10-24  James Gallagher <jgallagher at opendap.org>
+
+	tests pass for array projections in function arg lists
+
+2013-10-24  James Gallagher <jgallagher at opendap.org>
+
+	Fixed an obscure bug in the test function - for the scalar case it
+	was not reading the arg's value.
+
+2013-10-23  James Gallagher <jgallagher at opendap.org>
+
+	missed one baseline for the function stuff...
+
+2013-10-23  James Gallagher <jgallagher at opendap.org>
+
+	Added support for array subsetting (projection) in the argument
+	list of a function. Tests need work and there's an issue when the
+	function arg is a scalar not an array. Also, the intern_data()
+	methods don't work, but this may be a larger issue with the hack
+	to the function evaluation scheme added for 'grads syntax'
+	support.
+
+2013-10-21  hyoklee
+
+	fixed the bug #2016.
+
+2013-10-21  Hyo-Kyung Lee  <hyoklee at hdfgroup.org>
+
+	* escaping.cc (escattr): fixed the double escaping problem by changing
+	the order of the first two while() loops.
+
+2013-10-18  James Gallagher <jgallagher at opendap.org>
+
+	svn:ignore
+
+2013-10-17  James Gallagher <jgallagher at opendap.org>
+
+	Manually patched changes to Sequence::read_row and
+	TestSequence::read() from the DAP4 development branch so they work
+	with the newly modified handlers (the DAP4 branch uses _trunk_ copies
+	of the handlers). We will have to document this change before
+	releasing the code!
+
+	M    tests/TestSequence.cc
+	M    Sequence.cc
+
+2013-10-17  James Gallagher <jgallagher at opendap.org>
+
+	Added to svn:ignore
+
+2013-10-15  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+	A    gl/glthread
+	A    gl/glthread/threadlib.c
+	A    gl/glthread/lock.c
+	A    gl/glthread/lock.h
+
+2013-10-15  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+	AM   config.rpath
+
+2013-10-15  James Gallagher <jgallagher at opendap.org>
+
+	Added to gl
+
+	A    gl/m4/lib-link.m4
+	A    gl/m4/lock.m4
+	A    gl/m4/lib-prefix.m4
+	A    gl/m4/lib-ld.m4
+	A    gl/m4/eealloc.m4
+	A    gl/m4/extern-inline.m4
+	A    gl/m4/threadlib.m4
+	A    gl/wctype-h.c
+	A    gl/unistd.c
+
+2013-10-15  James Gallagher <jgallagher at opendap.org>
+
+	Updated gnulib.
+
+	M    XMLWriter.cc
+	M    conf/snippet/c++defs.h
+	M    conf/snippet/warn-on-use.h
+	M    conf/snippet/arg-nonnull.h
+	M    Byte.h
+	M    XDRUtils.cc
+	M    ServerFunction.cc
+	M    Url.cc
+	M    XDRFileUnMarshaller.cc
+	M    gl/m4/fcntl-o.m4
+	M    gl/m4/configmake.m4
+	M    gl/m4/localcharset.m4
+	M    gl/m4/locale_h.m4
+	M    gl/m4/sys_types_h.m4
+	M    gl/m4/mbrtowc.m4
+	M    gl/m4/btowc.m4
+	M    gl/m4/longlong.m4
+	M    gl/m4/00gnulib.m4
+	M    gl/m4/ssize_t.m4
+	M    gl/m4/glibc21.m4
+	M    gl/m4/localeconv.m4
+	M    gl/m4/codeset.m4
+	M    gl/m4/alloca.m4
+	M    gl/m4/off_t.m4
+	M    gl/m4/locale-fr.m4
+	M    gl/m4/langinfo_h.m4
+	M    gl/m4/wint_t.m4
+	M    gl/m4/mbsinit.m4
+	M    gl/m4/stdint.m4
+	M    gl/m4/gnulib-common.m4
+	M    gl/m4/stdbool.m4
+	M    gl/m4/malloc.m4
+	M    gl/m4/regex.m4
+	M    gl/m4/warn-on-use.m4
+	M    gl/m4/wchar_h.m4
+	M    gl/m4/gnulib-comp.m4
+	M    gl/m4/unistd_h.m4
+	M    gl/m4/wcrtomb.m4
+	M    gl/m4/locale-zh.m4
+	M    gl/m4/stddef_h.m4
+	M    gl/m4/gnulib-cache.m4
+	M    gl/m4/include_next.m4
+	M    gl/m4/mbstate_t.m4
+	M    gl/m4/wctype_h.m4
+	M    gl/m4/nl_langinfo.m4
+	M    gl/m4/locale-ja.m4
+	M    gl/m4/wchar_t.m4
+	M    gl/m4/multiarch.m4
+	M    gl/m4/stdlib_h.m4
+	M    gl/m4/mbtowc.m4
+	M    gl/m4/gnulib-tool.m4
+	M    gl/m4/byteswap.m4
+	M    gl/m4/extensions.m4
+	M    gl/localcharset.c
+	M    gl/mbsinit.c
+	M    gl/regex_internal.c
+	M    gl/malloc.c
+	M    gl/byteswap.in.h
+	M    gl/localcharset.h
+	M    gl/locale.in.h
+	M    gl/regex_internal.h
+	M    gl/sys_types.in.h
+	M    gl/wcrtomb.c
+	M    gl/btowc.c
+	M    gl/regexec.c
+	M    gl/ref-del.sin
+	M    gl/mbtowc.c
+	M    gl/regcomp.c
+	M    gl/mbtowc-impl.h
+	M    gl/streq.h
+	M    gl/alloca.in.h
+	M    gl/langinfo.in.h
+	M    gl/ref-add.sin
+	M    gl/verify.h
+	M    gl/regex.c
+	M    gl/config.charset
+	M    gl/mbrtowc.c
+	M    gl/wchar.in.h
+	M    gl/regex.h
+	M    gl/stdint.in.h
+	M    gl/stdbool.in.h
+	M    gl/unistd.in.h
+	M    gl/stddef.in.h
+	M    gl/localeconv.c
+	M    gl/wctype.in.h
+	M    gl/nl_langinfo.c
+	M    gl/Makefile.am
+	M    gl/gettext.h
+	M    gl/stdlib.in.h
+	M    BaseTypeFactory.cc
+	M    XDRStreamMarshaller.cc
+	M    escaping.cc
+	M    DapIndent.cc
+	M    XDRFileMarshaller.cc
+
+2013-10-01  James Gallagher <jgallagher at opendap.org>
+
+	Updated the FSF address in the copyright headers
+
+2013-09-30  James Gallagher <jgallagher at opendap.org>
+
+	This checkin contains a fix for the conflicting definitions of
+	width() in BaseType, Vector and Array, where Array provided a
+	version/definition that clashes with the one in BaseType. BaseType
+	defined width() and Array defined width(bool constrained = true),
+	which shadowed the former. I changed BaseType width so that its
+	signature is width(bool constrained = false) and made that the
+	only version of the method. There are some changes to uses of
+	width() in libdap and the BES, but not in the handlers.
+
+2013-09-27  James Gallagher <jgallagher at opendap.org>
+
+	misc changes; a minor fix for Array; a fix for the DDX parser; A
+	minor change in the scanners for the Error, DAS, DDS and CE
+	parsers (added %option noinput to suppress a warning); removed
+	-fno-defer-pop from the Makefile.ams.
+
+2013-09-17  James Gallagher <jgallagher at opendap.org>
+
+	I changed the character used for the Type special form (from # to
+	$, because # is a URL delim. and tomcat was filtering it).
+
+2013-08-28  James Gallagher <jgallagher at opendap.org>
+
+	Build/Audit fixes.
+
+	M    libdap/XDRFileUnMarshaller.cc
+	M    libdap/XDRFileUnMarshaller.h
+	M    bes/dispatch/unit-tests/keysT.cc
+	M    bes/functions/Makefile.am
+
+2013-08-27  James Gallagher <jgallagher at opendap.org>
+
+	Backed out an errant call to fclose()
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
 2013-08-28  James Gallagher <jgallagher at opendap.org>
 
 	Build/Audit fixes.
@@ -9612,5 +9994,5 @@ Mon Jul  8 16:25:11 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
 	Note that without Expect the GUI used for the transmission
 	progress indicator and error reporting is not available.
 
-$Id: ChangeLog 27104 2013-09-17 23:43:37Z jimg $
+$Id$
 
diff --git a/Clause.h b/Clause.h
index 56ccca9..9b4d11c 100644
--- a/Clause.h
+++ b/Clause.h
@@ -104,12 +104,8 @@ private:
     rvalue *_arg1;  // only for operator
     rvalue_list *_args;  // vector arg
 
-    Clause(const Clause &)
-    {}
-    Clause &operator=(const Clause &)
-    {
-        throw InternalErr(__FILE__, __LINE__, "Unimplemented method");
-    }
+    Clause(const Clause &);
+    Clause &operator=(const Clause &);
 
 public:
     Clause(const int oper, rvalue *a1, rvalue_list *rv);
diff --git a/Connect.cc b/Connect.cc
index 8ea727a..c118067 100644
--- a/Connect.cc
+++ b/Connect.cc
@@ -87,14 +87,14 @@ void Connect::process_data(DataDDS &data, Response *rs)
             throw InternalErr(__FILE__, __LINE__,
                     "An error was reported by the remote httpd; this should have been processed by HTTPConnect..");
 
-        case dap4_data_ddx: {
+        case dods_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);
+            read_multipart_headers(rs->get_stream(), "text/xml", dods_ddx);
 
             // Parse the DDX, reading up to and including the next boundary.
             // Return the CID for the matching data part
@@ -170,14 +170,14 @@ Connect::process_data(DDS &data, Response *rs)
         // 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: {
+    case dods_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);
+        read_multipart_headers(rs->get_stream(), "text/xml", dods_ddx);
 
         // Parse the DDX, reading up to and including the next boundary.
         // Return the CID for the matching data part
@@ -768,7 +768,6 @@ void Connect::request_ddx(DDS &dds, string expr)
             // (called by fetch_url) and result in a thrown Error object.
             break;
 
-        case dap4_ddx:
         case dods_ddx:
             try {
                 string blob;
@@ -837,7 +836,6 @@ void Connect::request_ddx_url(DDS &dds)
             // (called by fetch_url) and result in a thrown Error object.
             break;
 
-        case dap4_ddx:
         case dods_ddx:
             try {
                 string blob;
@@ -1068,7 +1066,7 @@ static void divine_type_information(Response *rs)
     // accepted both 'Dataset' and 'dataset' for a long time.
     switch (c) {
         case '-':
-            rs->set_type(dap4_data_ddx);
+            rs->set_type(dods_data_ddx);
             break;
         case 'D':
         case 'd':
@@ -1104,7 +1102,7 @@ void Connect::read_data_no_mime(DataDDS &data, Response *rs)
             d_protocol = rs->get_protocol();
             process_data(data, rs);
             break;
-        case dap4_data_ddx:
+        case dods_data_ddx:
             process_data(data, rs);
             d_version = rs->get_version();
             d_protocol = data.get_protocol();
@@ -1124,7 +1122,7 @@ void Connect::read_data_no_mime(DDS &data, Response *rs)
         d_protocol = rs->get_protocol();
         process_data(data, rs);
         break;
-    case dap4_data_ddx:
+    case dods_data_ddx:
         process_data(data, rs);
         d_version = rs->get_version();
         // TODO should check to see if this hack is a correct replacement
diff --git a/ConstraintEvaluator.cc b/ConstraintEvaluator.cc
index d66ff03..1332803 100644
--- a/ConstraintEvaluator.cc
+++ b/ConstraintEvaluator.cc
@@ -28,12 +28,13 @@
 
 #include "ServerFunctionsList.h"
 #include "ConstraintEvaluator.h"
+#include "Clause.h"
+#include "DataDDS.h"
 
 #include "ce_parser.h"
 #include "debug.h"
 #include "parser.h"
 #include "expr.h"
-//#include "ce_expr.tab.hh"
 
 struct yy_buffer_state;
 
@@ -162,119 +163,22 @@ void ConstraintEvaluator::append_constant(BaseType *btp)
     constants.push_back(btp);
 }
 
-// This code was removed when I switched from CE having it's own internal
-// list of functions to using an external list.
-#if 0
-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);
-}
-#endif
-
 /** @brief Find a Boolean function with a given name in the function list. */
 bool ConstraintEvaluator::find_function(const string &name, bool_func *f) const
 {
     return d_functions_list->find_function(name, f);
-#if 0
-    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;
-#endif
 }
 
 /** @brief Find a BaseType function with a given name in the function list. */
 bool ConstraintEvaluator::find_function(const string &name, btp_func *f) const
 {
     return d_functions_list->find_function(name, f);
-#if 0
-    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;
-#endif
 }
 
 /** @brief Find a projection function with a given name in the function list. */
 bool ConstraintEvaluator::find_function(const string &name, proj_func *f) const
 {
     return d_functions_list->find_function(name, f);
-#if 0
-    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;
-#endif
 }
 //@}
 
@@ -377,15 +281,6 @@ ConstraintEvaluator::eval_function_clauses(DDS &dds)
 /** @brief Evaluate a function-valued constraint expression that contains
  several function calls. Takes and returns a DataDDS.
 
- @todo Change this so that the new variables are inserted into the
- original DDS object - this will allow constraints that mix simple
- projections with function calls. The function is responsible for
- setting the new variable's read_p property and this 'evaluator'
- sets the send_p property. The original variables would have to be
- removed from the original DDS for this to work or the names of
- the new variables would have to not clash with the original variables'
- names.
-
  @see ConstraintEvaluator::eval_function_clauses(DataDDS &dds)
  @note Added for libdap 3.11 */
 DataDDS *
diff --git a/ConstraintEvaluator.h b/ConstraintEvaluator.h
index 1f37945..3ea8031 100644
--- a/ConstraintEvaluator.h
+++ b/ConstraintEvaluator.h
@@ -25,70 +25,35 @@
 #ifndef constraint_evaluator_h
 #define constraint_evaluator_h
 
-#include <list>
+#include <vector>
 
-#ifndef _dds_h
-#include "DDS.h"
-#endif
-
-#ifndef _datadds_h
-#include "DataDDS.h"
-#endif
-
-#ifndef _clause_h
-#include "Clause.h"
-#endif
+#include "expr.h"
+#include "RValue.h"
 
 namespace libdap
 {
 
+class DDS;
+class DataDDS;
+struct Clause;
 class ServerFunctionsList;
 
 /** @brief Evaluate a constraint expression */
 class ConstraintEvaluator
 {
 private:
-#if 0
-    // 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)
-        {}
-    };
-#endif
-    vector<Clause *> expr;      // List of CE Clauses
-
-    vector<BaseType *> constants;// List of temporary objects
-#if 0
-    list<function> functions; // Known external functions
-#endif
-    ServerFunctionsList *d_functions_list;  // Know external functions from
+    std::vector<Clause *> expr;      // List of CE Clauses
+
+    std::vector<BaseType *> constants;// List of temporary objects
+
+    ServerFunctionsList *d_functions_list;  // Known external functions from
                                             // modules
 
     // 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");
-    }
+    ConstraintEvaluator(const ConstraintEvaluator &);
+    ConstraintEvaluator &operator=(const ConstraintEvaluator &);
 
     friend class func_name_is;
 
@@ -98,22 +63,13 @@ public:
 
     typedef std::vector<BaseType *>::const_iterator Constants_citer ;
     typedef std::vector<BaseType *>::iterator Constants_iter ;
-#if 0
-    typedef std::list<function>::const_iterator Functions_citer ;
-    typedef std::list<function>::iterator Functions_iter ;
-#endif
 
     ConstraintEvaluator();
 
     virtual ~ConstraintEvaluator();
-#if 0
-    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);
-#endif
-    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;
+    bool find_function(const std::string &name, bool_func *f) const;
+    bool find_function(const std::string &name, btp_func *f) const;
+    bool find_function(const std::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);
@@ -121,8 +77,8 @@ public:
 
     bool functional_expression();
     bool boolean_expression();
-    bool eval_selection(DDS &dds, const string &dataset);
-    BaseType *eval_function(DDS &dds, const string &dataset);
+    bool eval_selection(DDS &dds, const std::string &dataset);
+    BaseType *eval_function(DDS &dds, const std::string &dataset);
 
     // New for libdap 3.11. These methods provide a way to evaluate multiple
     // functions in one CE
@@ -134,7 +90,7 @@ public:
     Clause_iter clause_end();
     bool clause_value(Clause_iter &i, DDS &dds);
 
-    void parse_constraint(const string &constraint, DDS &dds);
+    void parse_constraint(const std::string &constraint, DDS &dds);
     void append_constant(BaseType *btp);
 
 };
diff --git a/Constructor.cc b/Constructor.cc
index 571d1da..8a1fdec 100644
--- a/Constructor.cc
+++ b/Constructor.cc
@@ -37,18 +37,28 @@
 #include <algorithm>
 #include <functional>
 
+#include <stdint.h>
+
 //#define DODS_DEBUG
 
+#include "crc.h"
+
 #include "Constructor.h"
 #include "Grid.h"
 
+#include "DMR.h"
+#include "XMLWriter.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
+#include "D4Attributes.h"
+
 #include "debug.h"
 #include "escaping.h"
 #include "util.h"
 #include "Error.h"
 #include "InternalErr.h"
 
-
 using namespace std;
 
 namespace libdap {
@@ -58,19 +68,25 @@ namespace libdap {
 void
 Constructor::m_duplicate(const Constructor &c)
 {
-    Constructor &cs = const_cast<Constructor &>(c);
+	DBG(cerr << "In Constructor::m_duplicate for " << c.name() << endl);
+	// Clear out any spurious vars in Constructor::d_vars
+	// Moved from Grid::m_duplicate. jhrg 4/3/13
+	d_vars.clear(); // [mjohnson 10 Sep 2009]
 
-    for (Vars_iter i = cs.d_vars.begin(); i != cs.d_vars.end(); i++) {
-        BaseType *btp = (*i)->ptr_duplicate();
-        btp->set_parent(this);
-        d_vars.push_back(btp);
-    }
+	Vars_citer i = c.d_vars.begin();
+	while (i != c.d_vars.end()) {
+		BaseType *btp = (*i++)->ptr_duplicate();
+		btp->set_parent(this);
+		d_vars.push_back(btp);
+	}
+
+	DBG(cerr << "Exiting Constructor::m_duplicate for " << c.name() << endl);
 }
 
 // Public member functions
 
-Constructor::Constructor(const string &n, const Type &t, bool is_dap4)
-        : BaseType(n, t, is_dap4)
+Constructor::Constructor(const string &name, const Type &type, bool is_dap4)
+        : BaseType(name, type, is_dap4)
 {}
 
 /** Server-side constructor that takes the name of the variable to be
@@ -78,24 +94,33 @@ Constructor::Constructor(const string &n, const Type &t, bool is_dap4)
  * 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
+ * @param name string containing the name of the variable to be created
+ * @param dataset string containing the name of the dataset from which this
  * variable is being created
- * @param t type of data being stored
+ * @param type type of data being stored
  */
-Constructor::Constructor(const string &n, const string &d, const Type &t, bool is_dap4)
-        : BaseType(n, d, t, is_dap4)
+Constructor::Constructor(const string &name, const string &dataset, const Type &type, bool is_dap4)
+        : BaseType(name, dataset, type, is_dap4)
 {}
 
 Constructor::Constructor(const Constructor &rhs) : BaseType(rhs), d_vars(0)
-{}
+{
+    DBG(cerr << "In Constructor::copy_ctor for " << rhs.name() << endl);
+    m_duplicate(rhs);
+}
 
 Constructor::~Constructor()
-{}
+{
+    Vars_iter i = d_vars.begin();
+    while (i != d_vars.end()) {
+        delete *i++;
+    }
+}
 
 Constructor &
 Constructor::operator=(const Constructor &rhs)
 {
+    DBG(cerr << "Entering Constructor::operator=" << endl);
     if (this == &rhs)
         return *this;
 
@@ -103,9 +128,43 @@ Constructor::operator=(const Constructor &rhs)
 
     m_duplicate(rhs);
 
+    DBG(cerr << "Exiting Constructor::operator=" << endl);
     return *this;
 }
 
+// A public method, but just barely..
+BaseType *
+Constructor::transform_to_dap4(D4Group *root, Constructor *dest)
+{
+    for (Constructor::Vars_citer i = var_begin(), e = var_end(); i != e; ++i) {
+    	BaseType *new_var = (*i)->transform_to_dap4(root, dest);
+    	if (new_var) {	// Might be a Grid; see the comment in BaseType::transform_to_dap4()
+    		new_var->set_parent(dest);
+    		dest->add_var_nocopy(new_var);
+    	}
+    }
+
+    // Add attributes
+	dest->attributes()->transform_to_dap4(get_attr_table());
+
+    dest->set_is_dap4(true);
+
+	return dest;
+}
+
+string
+Constructor::FQN() const
+{
+	if (get_parent() == 0)
+		return name();
+	else if (get_parent()->type() == dods_group_c)
+		return get_parent()->FQN() + name();
+	else if (get_parent()->type() == dods_array_c)
+		return get_parent()->FQN();
+	else
+		return get_parent()->FQN() + "." + name();
+}
+
 int
 Constructor::element_count(bool leaves)
 {
@@ -162,11 +221,11 @@ Constructor::width()
     @return  The number of bytes used by the variable.
  */
 unsigned int
-Constructor::width(bool constrained)
+Constructor::width(bool constrained) const
 {
     unsigned int sz = 0;
 
-    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
+    for (Vars_citer i = d_vars.begin(); i != d_vars.end(); i++) {
         if (constrained) {
             if ((*i)->send_p())
                 sz += (*i)->width(constrained);
@@ -194,6 +253,8 @@ Constructor::var(const string &name, bool exact_match, btp_stack *s)
 BaseType *
 Constructor::var(const string &n, btp_stack &s)
 {
+	// This should probably be removed. The BES code should remove web encoding
+	// with the possible exception of spaces. jhrg 11/25/13
     string name = www2id(n);
 
     BaseType *btp = m_exact_match(name, &s);
@@ -361,6 +422,7 @@ Constructor::add_var_nocopy(BaseType *bt, Part)
 void
 Constructor::del_var(const string &n)
 {
+	// TODO remove_if? find_if?
     for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
         if ((*i)->name() == n) {
             BaseType *bt = *i ;
@@ -388,6 +450,7 @@ Constructor::del_var(Vars_iter i)
  */
 bool Constructor::read()
 {
+	DBG(cerr << "Entering  Constructor::read..." << endl);
     if (!read_p()) {
         for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
             (*i)->read();
@@ -401,7 +464,7 @@ bool Constructor::read()
 void
 Constructor::intern_data(ConstraintEvaluator & eval, DDS & dds)
 {
-    DBG(cerr << "Structure::intern_data: " << name() << endl);
+    DBG(cerr << "Constructor::intern_data: " << name() << endl);
     if (!read_p())
         read();          // read() throws Error and InternalErr
 
@@ -420,10 +483,8 @@ Constructor::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool
     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();
 
@@ -439,7 +500,9 @@ Constructor::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool
             if (sm && sm->checksums() && (*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
                 sm->get_checksum();
 #else
-            (*i)->serialize(eval, dds, m, false);
+            // (*i)->serialize(eval, dds, m, false);
+            // Only Sequence and Vector run the evaluator.
+            (*i)->serialize(eval, dds, m, true);
 #endif
         }
     }
@@ -458,6 +521,73 @@ Constructor::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
 }
 
 void
+Constructor::compute_checksum(Crc32 &)
+{
+	throw InternalErr(__FILE__, __LINE__, "Computing a checksum alone is not supported for Constructor types.");
+}
+
+void
+Constructor::intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator & eval*/)
+{
+    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
+        if ((*i)->send_p()) {
+            (*i)->intern_data(checksum/*, dmr, eval*/);
+        }
+    }
+}
+
+
+/**
+ * @brief Serialize a Constructor
+ *
+ * @todo See notebook for 8/21/14
+ *
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+Constructor::serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter)
+{
+#if 1
+	// Not used for the same reason the equivalent code in D4Group::serialize()
+	// is not used. Fail for D4Sequence and general issues with memory use.
+	//
+	// Revisit this - I had to uncomment this to get the netcdf_handler code
+	// to work - it relies on having NCStructure::read() called. The D4Sequence
+	// ::serialize() method calls read_next_instance(). What seems to be happening
+	// is that this call to read gets the first set of values, but does not store
+	// them; the call to serialize then runs the D4Sequence::serialize() method that
+	// _does_ read all of the sequence data and then serialize it. However, the first
+	// sequence instance is missing...
+    if (!read_p())
+        read();  // read() throws Error
+#endif
+#if 0
+    // place holder for now. There may be no need for this; only Array and Seq?
+    // jhrg 9/6/13
+    if (filter && !eval.eval_selection(dmr, dataset()))
+        return true;
+#endif
+
+    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
+        if ((*i)->send_p()) {
+            (*i)->serialize(m, dmr, /*eval,*/ filter);
+        }
+    }
+}
+
+void
+Constructor::deserialize(D4StreamUnMarshaller &um, DMR &dmr)
+{
+    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
+        (*i)->deserialize(um, dmr);
+    }
+}
+
+void
 Constructor::print_decl(FILE *out, string space, bool print_semi,
                         bool constraint_info, bool constrained)
 {
@@ -568,17 +698,67 @@ Constructor::print_xml_writer(XMLWriter &xml, bool constrained)
         if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
             throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
 
-    bool has_attributes = get_attr_table().get_size() > 0;
-    bool has_variables = (var_begin() != var_end());
-    if (has_attributes)
+    // DAP2 prints attributes first. For some reason we decided that DAP4 should
+    // print them second. No idea why... jhrg 8/15/14
+    if (!is_dap4() && get_attr_table().get_size() > 0)
         get_attr_table().print_xml_writer(xml);
+
+    bool has_variables = (var_begin() != var_end());
     if (has_variables)
         for_each(var_begin(), var_end(), PrintFieldXMLWriter(xml, constrained));
 
+    if (is_dap4())
+        attributes()->print_dap4(xml);
+
+#if 0
+    // Moved up above so that the DDX tests for various handles will still work.
+    // jhrg 8/15/14
+    if (!is_dap4() && get_attr_table().get_size() > 0)
+        get_attr_table().print_xml_writer(xml);
+#endif
+
+    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
+}
+
+class PrintDAP4FieldXMLWriter : public unary_function<BaseType *, void>
+{
+    XMLWriter &d_xml;
+    bool d_constrained;
+public:
+    PrintDAP4FieldXMLWriter(XMLWriter &x, bool c) : d_xml(x), d_constrained(c) {}
+
+    void operator()(BaseType *btp)
+    {
+        btp->print_dap4(d_xml, d_constrained);
+    }
+};
+
+
+void
+Constructor::print_dap4(XMLWriter &xml, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)type_name().c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
+
+    if (!name().empty())
+        if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
+            throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+
+    bool has_variables = (var_begin() != var_end());
+    if (has_variables)
+        for_each(var_begin(), var_end(), PrintDAP4FieldXMLWriter(xml, constrained));
+
+    attributes()->print_dap4(xml);
+
     if (xmlTextWriterEndElement(xml.get_writer()) < 0)
         throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
 }
 
+
 bool
 Constructor::check_semantics(string &msg, bool all)
 {
diff --git a/Constructor.h b/Constructor.h
index 39479ac..995cca1 100644
--- a/Constructor.h
+++ b/Constructor.h
@@ -30,9 +30,15 @@
 
 #include "BaseType.h"
 
+class Crc32;
+
 namespace libdap
 {
 
+class DMR;
+class XMLWriter;
+class D4StreamUnMarshaller;
+
 /** Common methods for all constructor types. */
 class Constructor: public BaseType
 {
@@ -46,8 +52,8 @@ protected:
     BaseType *m_leaf_match(const string &name, btp_stack *s = 0);
     BaseType *m_exact_match(const string &name, btp_stack *s = 0);
 
-    Constructor(const string &n, const Type &t, bool is_dap4 = false);
-    Constructor(const string &n, const string &d, const Type &t, bool is_dap4 = false);
+    Constructor(const string &name, const Type &type, bool is_dap4 = false);
+    Constructor(const string &name, const string &d, const Type &type, bool is_dap4 = false);
 
     Constructor(const Constructor &copy_from);
 
@@ -59,19 +65,21 @@ public:
     virtual ~Constructor();
 
     Constructor &operator=(const Constructor &rhs);
+    BaseType *transform_to_dap4(D4Group *root, Constructor *dest);
 
-    //virtual void transfer_attributes(AttrTable *at_container);
+    virtual std::string FQN() const;
 
     virtual int element_count(bool leaves = false);
 
     virtual void set_send_p(bool state);
     virtual void set_read_p(bool state);
 
-    /// @deprecated
-    virtual unsigned int width(bool constrained = false);
+    virtual unsigned int width(bool constrained = false) const;
 #if 0
     virtual unsigned int width(bool constrained);
 #endif
+    // TODO Rewrite these methods to use the back pointers and keep this
+    // for older code.
     /// btp_stack no longer needed; use back pointers (BaseType::get_parent())
     virtual BaseType *var(const string &name, bool exact_match = true, btp_stack *s = 0);
     /// @deprecated
@@ -91,10 +99,18 @@ public:
     virtual void del_var(Vars_iter i);
 
     virtual bool read();
+
+    // DAP2
     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);
 
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator &eval*/);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
     // Do not store values in memory as for C; users work with the C++ objects
     virtual unsigned int val2buf(void *, bool) {
         throw InternalErr(__FILE__, __LINE__, "Never use this method; see the programmer's guide documentation.");
@@ -114,6 +130,8 @@ public:
     virtual void print_xml(ostream &out, string space = "    ",
                            bool constrained = false);
 
+    void print_dap4(XMLWriter &xml, bool constrained = false);
+
     virtual void print_xml_writer(XMLWriter &xml, bool constrained = false);
 
     virtual void print_decl(FILE *out, string space = "    ",
diff --git a/D4AsyncUtil.cc b/D4AsyncUtil.cc
new file mode 100644
index 0000000..ac4e73a
--- /dev/null
+++ b/D4AsyncUtil.cc
@@ -0,0 +1,357 @@
+/*
+ * D4AsyncUtil.cc
+ *
+ *  Created on: Feb 18, 2014
+ *      Author: ndp
+ */
+
+#include "config.h"
+
+#include <sstream>
+
+#include "XMLWriter.h"
+
+#include "Error.h"
+#include "InternalErr.h"
+#include "util.h"
+
+#include "D4AsyncUtil.h"
+#include "DapXmlNamespaces.h"
+
+namespace libdap {
+
+const string D4AsyncUtil::STYLESHEET_REFERENCE_KEY = "DAP.Async.StyleSheet.Ref";
+
+D4AsyncUtil::D4AsyncUtil()  {}
+
+D4AsyncUtil::~D4AsyncUtil() {}
+
+/**
+ * @brief Print the AsyncRequired response to the.
+ * Print the AsyncRequired in XML form.
+ * @param xml Print to this XMLWriter instance
+ */
+void D4AsyncUtil::writeD4AsyncRequired(XMLWriter &xml, long expectedDelay, long responseLifetime, string *stylesheet_ref) {
+
+	// ------ AsynchronousResponse Element and Attributes - BEGIN
+
+	/*
+	int	xmlTextWriterWriteAttributeNS	(xmlTextWriterPtr writer,
+						 const xmlChar * prefix,
+						 const xmlChar * name,
+						 const xmlChar * namespaceURI,
+						 const xmlChar * content)
+	*/
+
+	if(stylesheet_ref){
+		string href = "href='" + *stylesheet_ref +"'";
+		if(xmlTextWriterStartPI(xml.get_writer(), (const xmlChar*) "xml-stylesheet") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not start XML Processing Instruction.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) "type='text/xsl'") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) " ") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) href.c_str()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterEndPI(xml.get_writer()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not Close XML Processing Instruction.");
+	}
+
+	DapXmlNamspaces dapns;
+	if (xmlTextWriterStartElementNS(xml.get_writer(),
+			(const xmlChar*)"dap",
+			(const xmlChar*) "AsynchronousResponse",
+			(const xmlChar*) dapns.getDapNamespaceString(DAP_4_0).c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write AsynchronousResponse element");
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "status", (const xmlChar *) "required") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'status'");
+
+
+	// ------ expectedDelay Element and Attributes
+	if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "dap:expectedDelay") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write expectedDelay element");
+	ostringstream oss;
+	oss << expectedDelay;
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "seconds", (const xmlChar*) oss.str().c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'status'");
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end expectedDelay element");
+	// ------ expectedDelay Element and Attributes - END
+
+
+	// ------ responseLifetime Element and Attributes
+	if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "dap:responseLifetime") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write expectedDelay element");
+	ostringstream oss2;
+	oss2 << responseLifetime;
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "seconds", (const xmlChar*) oss2.str().c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'seconds'");
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end responseLifetime element");
+	// ------ responseLifetime Element and Attributes - END
+
+
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end AsynchronousResponse element");
+	// ------ AsynchronousResponse Element and Attributes - END
+}
+
+
+/**
+ * @brief Print the AsyncRequired response to the.
+ * Print the AsyncRequired in XML form.
+ * @param xml Print to this XMLWriter instance
+ */
+void D4AsyncUtil::writeD4AsyncAccepted(XMLWriter &xml, long expectedDelay, long responseLifetime, string asyncResourceUrl, string *stylesheet_ref)  {
+
+	// ------ AsynchronousResponse Element and Attributes - BEGIN
+	DapXmlNamspaces dapns;
+
+	if(stylesheet_ref){
+		string href = "href='" + *stylesheet_ref +"'";
+		if(xmlTextWriterStartPI(xml.get_writer(), (const xmlChar*) "xml-stylesheet") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not start XML Processing Instruction.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) "type='text/xsl'") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) " ") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) href.c_str()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterEndPI(xml.get_writer()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not Close XML Processing Instruction.");
+	}
+
+	if (xmlTextWriterStartElementNS(xml.get_writer(),
+			(const xmlChar*)"dap",
+			(const xmlChar*) "AsynchronousResponse",
+			(const xmlChar*) dapns.getDapNamespaceString(DAP_4_0).c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write AsynchronousResponse element");
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "status", (const xmlChar *) "accepted") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'status'");
+
+
+	// ------ expectedDelay Element and Attributes
+	if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "dap:expectedDelay") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write expectedDelay element");
+	ostringstream oss;
+	oss << expectedDelay;
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "seconds", (const xmlChar*) oss.str().c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'seconds'");
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end expectedDelay element");
+	// ------ expectedDelay Element and Attributes - END
+
+
+	// ------ responseLifetime Element and Attributes
+	if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "dap:responseLifetime") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write expectedDelay element");
+	ostringstream oss2;
+	oss2 << responseLifetime;
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "seconds", (const xmlChar*) oss2.str().c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'seconds'");
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end responseLifetime element");
+	// ------ responseLifetime Element and Attributes - END
+
+
+	// ------ link Element and Attributes
+	if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "dap:link") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write expectedDelay element");
+
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "href", (const xmlChar*) asyncResourceUrl.c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'href'");
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end link element");
+	// ------ link Element and Attributes - END
+
+
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end AsynchronousResponse element");
+	// ------ AsynchronousResponse Element and Attributes - END
+}
+
+/**
+ * @brief Print the AsyncRequired response to the.
+ * Print the AsyncRequired in XML form.
+ * @param xml Print to this XMLWriter instance
+ */
+void D4AsyncUtil::writeD4AsyncPending(XMLWriter &xml, string *stylesheet_ref)  {
+
+	// ------ AsynchronousResponse Element and Attributes - BEGIN
+	DapXmlNamspaces dapns;
+
+
+	if(stylesheet_ref){
+		string href = "href='" + *stylesheet_ref +"'";
+		if(xmlTextWriterStartPI(xml.get_writer(), (const xmlChar*) "xml-stylesheet") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not start XML Processing Instruction.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) "type='text/xsl'") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) " ") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) href.c_str()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterEndPI(xml.get_writer()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not Close XML Processing Instruction.");
+	}
+
+	if (xmlTextWriterStartElementNS(xml.get_writer(),
+			(const xmlChar*)"dap",
+			(const xmlChar*) "AsynchronousResponse",
+			(const xmlChar*) dapns.getDapNamespaceString(DAP_4_0).c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write AsynchronousResponse element");
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "status", (const xmlChar *) "pending") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'status'");
+
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end AsynchronousResponse element");
+	// ------ AsynchronousResponse Element and Attributes - END
+}
+
+
+/**
+ * @brief Print the AsyncRequired response to the.
+ * Print the AsyncRequired in XML form.
+ * @param xml Print to this XMLWriter instance
+ */
+void D4AsyncUtil::writeD4AsyncResponseGone(XMLWriter &xml, string *stylesheet_ref)  {
+
+	// ------ AsynchronousResponse Element and Attributes - BEGIN
+	DapXmlNamspaces dapns;
+
+
+	if(stylesheet_ref){
+		string href = "href='" + *stylesheet_ref +"'";
+		if(xmlTextWriterStartPI(xml.get_writer(), (const xmlChar*) "xml-stylesheet") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not start XML Processing Instruction.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) "type='text/xsl'") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) " ") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) href.c_str()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterEndPI(xml.get_writer()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not Close XML Processing Instruction.");
+	}
+
+	if (xmlTextWriterStartElementNS(xml.get_writer(),
+			(const xmlChar*)"dap",
+			(const xmlChar*) "AsynchronousResponse",
+			(const xmlChar*) dapns.getDapNamespaceString(DAP_4_0).c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write AsynchronousResponse element");
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "status", (const xmlChar *) "gone") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'status'");
+
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end AsynchronousResponse element");
+	// ------ AsynchronousResponse Element and Attributes - END
+}
+
+
+/**
+ * @brief Print the AsyncRequired response to the.
+ * Print the AsyncRequired in XML form.
+ * @param xml Print to this XMLWriter instance
+ */
+void D4AsyncUtil::writeD4AsyncResponseRejected(XMLWriter &xml, RejectReasonCode code, string description, string *stylesheet_ref) {
+
+	// ------ AsynchronousResponse Element and Attributes - BEGIN
+	DapXmlNamspaces dapns;
+
+
+	if(stylesheet_ref){
+		string href = "href='" + *stylesheet_ref +"'";
+		if(xmlTextWriterStartPI(xml.get_writer(), (const xmlChar*) "xml-stylesheet") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not start XML Processing Instruction.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) "type='text/xsl'") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) " ") < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) href.c_str()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not write Processing Instruction content.");
+		if(xmlTextWriterEndPI(xml.get_writer()) < 0)
+			throw InternalErr(__FILE__, __LINE__, "Could not Close XML Processing Instruction.");
+	}
+
+	if (xmlTextWriterStartElementNS(xml.get_writer(),
+			(const xmlChar*)"dap",
+			(const xmlChar*) "AsynchronousResponse",
+			(const xmlChar*) dapns.getDapNamespaceString(DAP_4_0).c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write AsynchronousResponse element");
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "status", (const xmlChar *) "rejected") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'status'");
+
+	// ------ reason Element and Attributes
+	if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "dap:reason") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write reason element");
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "code", (const xmlChar*) getRejectReasonCodeString(code).c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for 'code'");
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end reason element");
+	// ------ reason Element and Attributes - END
+
+
+	// ------ description Element and Attributes
+	if (xmlTextWriterWriteElement(xml.get_writer(), (const xmlChar*) "dap:description", (const xmlChar*) description.c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write description element");
+
+	// ------ description Element and Attributes - END
+
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end AsynchronousResponse element");
+	// ------ AsynchronousResponse Element and Attributes - END
+
+
+}
+
+string D4AsyncUtil::getRejectReasonCodeString(RejectReasonCode code){
+
+	string codeStr;
+	switch(code){
+	case TIME:
+		codeStr = "time";
+		break;
+
+	case UNAVAILABLE:
+		codeStr = "unavailable";
+		break;
+
+	case PRIVILEGES:
+		codeStr = "privileges";
+		break;
+
+	case OTHER:
+		codeStr = "other";
+		break;
+
+	default:
+		throw InternalErr(__FILE__, __LINE__, "D4AsyncUtil::getRejectReasonCodeString() - Unrecognized reject_reason_code.");
+		break;
+
+	}
+	return codeStr;
+}
+
+// Unused paramters generate warnings, so I removed/commented them below. jhrg 3/12/14
+void D4AsyncUtil::writeD2AsyncRequired(XMLWriter &/*xml*/, long /*expectedDelay*/, long /*responseLifetime*/)  {
+	throw InternalErr(__FILE__, __LINE__, "DAP2 Doesn't handle Async.");
+}
+
+void D4AsyncUtil::writeD2AsyncAccepted(XMLWriter &, long , long , string /*asyncResourceUrl*/)  {
+	throw InternalErr(__FILE__, __LINE__, "DAP2 Doesn't handle Async.");
+}
+
+
+void D4AsyncUtil::writeD2AsyncPending(XMLWriter &)  {
+	throw InternalErr(__FILE__, __LINE__, "DAP2 Doesn't handle Async.");
+}
+
+void D4AsyncUtil::writeD2AsyncResponseGone(XMLWriter &)  {
+	throw InternalErr(__FILE__, __LINE__, "DAP2 Doesn't handle Async.");
+}
+
+void D4AsyncUtil::writeD2AsyncResponseRejected(XMLWriter &, RejectReasonCode /*code*/, string /*description*/)  {
+	throw InternalErr(__FILE__, __LINE__, "DAP2 Doesn't handle Async.");
+}
+
+} /* namespace libdap */
diff --git a/D4AsyncUtil.h b/D4AsyncUtil.h
new file mode 100644
index 0000000..f31f0f9
--- /dev/null
+++ b/D4AsyncUtil.h
@@ -0,0 +1,86 @@
+/*
+ * D4AsyncUtil.h
+ *
+ *  Created on: Feb 18, 2014
+ *      Author: ndp
+ */
+
+#ifndef D4ASYNCUTIL_H_
+#define D4ASYNCUTIL_H_
+
+#include "XMLWriter.h"
+
+namespace libdap {
+
+
+enum RejectReasonCode { TIME, UNAVAILABLE, PRIVILEGES, OTHER };
+
+
+class D4AsyncUtil {
+private:
+#if 0
+    // Not used
+	string *d_stylesheet_ref;
+#endif
+
+public:
+	D4AsyncUtil();
+	virtual ~D4AsyncUtil();
+
+	const static string STYLESHEET_REFERENCE_KEY;
+
+
+	/**
+	 * @brief Write the DAP4 AsyncRequired response.
+	 * Print the AsyncRequired in XML form.
+	 * @param xml Print to this XMLWriter instance
+	 */
+	void writeD4AsyncRequired(XMLWriter &xml, long expectedDelay, long responseLifetime, string *stylesheet_ref=0);
+
+
+	/**
+	 * @brief Write the DAP4 AsyncAccepted response.
+	 * Write the AsyncAccepted in XML form.
+	 * @param xml Print to this XMLWriter instance
+	 */
+	void writeD4AsyncAccepted(XMLWriter &xml, long expectedDelay, long responseLifetime, string asyncResourceUrl, string *stylesheet_ref=0);
+
+	/**
+	 * @brief Write the DAP4 AsyncPending response.
+	 * Write the DAP4 AsyncPending in XML form.
+	 * @param xml Print to this XMLWriter instance
+	 */
+	void writeD4AsyncPending(XMLWriter &xml, string *stylesheet_ref=0);
+
+
+	/**
+	 * @brief Write the DAP4 AsyncResponseGone response.
+	 * Write the DAP4 AsyncRequired in XML form.
+	 * @param xml Print to this XMLWriter instance
+	 */
+	void writeD4AsyncResponseGone(XMLWriter &xml, string *stylesheet_ref=0);
+
+	/**
+	 * @brief Write the DAP4 ResponseRejected response.
+	 * Write the DAP4 AsyncRequired in XML form.
+	 * @param xml Print to this XMLWriter instance
+	 */
+	void writeD4AsyncResponseRejected(XMLWriter &xml, RejectReasonCode code, string description, string *stylesheet_ref=0);
+	string getRejectReasonCodeString(RejectReasonCode code);
+
+	/**
+	 * @brief Write the DAP2 AsyncRequired response .
+	 * Write the DAP2 AsyncRequired in XML form.
+	 * @param xml Print to this XMLWriter instance
+	 */
+	void writeD2AsyncRequired(XMLWriter &xml, long expectedDelay, long responseLifetime);
+	void writeD2AsyncAccepted(XMLWriter &xml, long expectedDelay, long responseLifetime, string asyncResourceUrl);
+	void writeD2AsyncPending(XMLWriter &xml);
+	void writeD2AsyncResponseGone(XMLWriter &xml);
+	void writeD2AsyncResponseRejected(XMLWriter &xml, RejectReasonCode code, string description);
+
+
+};
+
+} /* namespace libdap */
+#endif /* D4ASYNCUTIL_H_ */
diff --git a/D4ParseError.h b/D4AttributeType.h
similarity index 51%
copy from D4ParseError.h
copy to D4AttributeType.h
index ede678f..80960cf 100644
--- a/D4ParseError.h
+++ b/D4AttributeType.h
@@ -1,10 +1,9 @@
-
 // -*- mode: c++; c-basic-offset:4 -*-
 
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
 // Access Protocol.
 
-// Copyright (c) 2012 OPeNDAP, Inc.
+// Copyright (c) 2013 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -19,31 +18,50 @@
 //
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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 d4_parse_error_h
-#define d4_parse_error_h
+#ifndef d4attributetype_h
+#define d4attributetype_h
+
+/** D4AttributeType identifies the data type stored in a particular attribute
+
+    @see D4Attributes
+*/
+
+enum D4AttributeType {
+    attr_null_c,
+
+    attr_byte_c,
+    attr_int16_c,
+    attr_uint16_c,
+    attr_int32_c,  // Added `attr_' to fix clash with IRIX 5.3.
+    attr_uint32_c,
+    attr_float32_c,
+    attr_float64_c,
+    attr_str_c,
+    attr_url_c,
 
-#ifndef _error_h
-#include "Error.h"
+    // Added for DAP4
+    attr_int8_c,
+    attr_uint8_c,
+
+    attr_int64_c,
+    attr_uint64_c,
+
+#if 0
+    // just use attr_url_c. jhrg 8/15/13
+    attr_url4_c,
 #endif
 
-namespace libdap
-{
-
-/** Thrown when the DDX response cannot be parsed.. */
-class D4ParseError : public Error
-{
-public:
-    D4ParseError() : Error("The DDX response document parse failed.")
-    {}
-    D4ParseError(const string &msg) :
-            Error(string("The DDX response document parse failed: ") + msg)
-    {}
-};
+    attr_enum_c,
+    attr_opaque_c,
 
-} // namespace libdap
+    // These are specific to attributes while the other types are
+    // also supported by the variables. jhrg 4/17/13
+    attr_container_c,
+    attr_otherxml_c
+};
 
-#endif // d4_parse_error_h
+#endif /* d4attributetype_h */
diff --git a/D4Attributes.cc b/D4Attributes.cc
new file mode 100644
index 0000000..4aee9d8
--- /dev/null
+++ b/D4Attributes.cc
@@ -0,0 +1,393 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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
+
+#include "D4Attributes.h"
+#include "D4AttributeType.h"
+#include "InternalErr.h"
+
+#include "AttrTable.h"
+
+#include "util.h"
+#include "debug.h"
+
+namespace libdap {
+
+/** Convert an AttrType to it's string representation.
+ @param at The Attribute Type.
+ @return The type's string representation */
+string D4AttributeTypeToString(D4AttributeType at)
+{
+    switch(at) {
+        case attr_null_c:
+            return "null";
+
+        case attr_byte_c:
+            return "Byte";
+
+        case attr_int16_c:
+            return "Int16";
+
+        case attr_uint16_c:
+            return "UInt16";
+
+        case attr_int32_c:
+            return "Int32";
+
+        case attr_uint32_c:
+            return "UInt32";
+
+        case attr_float32_c:
+            return "Float32";
+
+        case attr_float64_c:
+            return "Float64";
+
+        case attr_str_c:
+            return "String";
+
+        case attr_url_c:
+            return "Url";
+
+        // Added for DAP4
+        case attr_int8_c:
+            return "Int8";
+
+        case attr_uint8_c:
+            return "UInt8";
+
+        case attr_int64_c:
+            return "Int64";
+
+        case attr_uint64_c:
+            return "UInt64";
+
+        case attr_enum_c:
+            return "Enum";
+
+        case attr_opaque_c:
+            return "Opaque";
+
+        // These are specific to attributes while the other types are
+        // also supported by the variables. jhrg 4/17/13
+        case attr_container_c:
+            return "Container";
+
+        case attr_otherxml_c:
+            return "OtherXML";
+
+        default:
+            throw InternalErr(__FILE__, __LINE__, "Unsupported attribute type");
+    }
+}
+
+D4AttributeType StringToD4AttributeType(string s)
+{
+    downcase(s);
+
+    if (s == "container")
+        return attr_container_c;
+
+    else if (s == "byte")
+        return attr_byte_c;
+    else if (s == "int8")
+        return attr_int8_c;
+    else if (s == "uint8")
+        return attr_uint8_c;
+    else if (s == "int16")
+        return attr_int16_c;
+    else if (s == "uint16")
+        return attr_uint16_c;
+    else if (s == "int32")
+        return attr_int32_c;
+    else if (s == "uint32")
+        return attr_uint32_c;
+    else if (s == "int64")
+        return attr_int64_c;
+    else if (s == "uint64")
+        return attr_uint64_c;
+
+    else if (s == "float32")
+        return attr_float32_c;
+    else if (s == "float64")
+        return attr_float64_c;
+
+    else if (s == "string")
+        return attr_str_c;
+    else if (s == "url")
+        return attr_url_c;
+    else if (s == "otherxml")
+        return attr_otherxml_c;
+    else
+        return attr_null_c;
+}
+
+void
+D4Attribute::m_duplicate(const D4Attribute &src)
+{
+    d_name = src.d_name;
+    d_type = src.d_type;
+    d_values = src.d_values;
+    if (src.d_attributes)
+        d_attributes = new D4Attributes(*src.d_attributes);
+    else
+        d_attributes = 0;
+}
+
+D4Attribute::D4Attribute(const D4Attribute &src)
+{
+    m_duplicate(src);
+}
+
+D4Attribute::~D4Attribute()
+{
+    delete d_attributes;
+}
+
+D4Attribute &
+D4Attribute::operator=(const D4Attribute &rhs)
+{
+    if (this == &rhs) return *this;
+    m_duplicate(rhs);
+    return *this;
+}
+
+D4Attributes *
+D4Attribute::attributes()
+{
+    if (!d_attributes) d_attributes = new D4Attributes();
+    return d_attributes;
+}
+
+/** @brief copy attributes from DAP2 to DAP4
+ *
+ * Given a DAP2 AttrTable, copy all of its attributes into a DAP4 D4Attributes
+ * object.
+ *
+ * @param at Read the DAP2 attributes from here.
+ */
+void
+D4Attributes::transform_to_dap4(AttrTable &at)
+{
+	// for every attribute in at, copy it to this.
+	for (AttrTable::Attr_iter i = at.attr_begin(), e = at.attr_end(); i != e; ++i) {
+		string name = at.get_name(i);
+		AttrType type = at.get_attr_type(i);
+
+		switch (type) {
+		case Attr_container: {
+			D4Attribute *a = new D4Attribute(name, attr_container_c);
+			D4Attributes *attributes = a->attributes(); // allocates a new object
+			attributes->transform_to_dap4(*at.get_attr_table(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_byte: {
+			D4Attribute *a = new D4Attribute(name, attr_byte_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_int16: {
+			D4Attribute *a = new D4Attribute(name, attr_int16_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_uint16: {
+			D4Attribute *a = new D4Attribute(name, attr_uint16_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_int32: {
+			D4Attribute *a = new D4Attribute(name, attr_int32_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_uint32: {
+			D4Attribute *a = new D4Attribute(name, attr_uint32_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_float32: {
+			D4Attribute *a = new D4Attribute(name, attr_byte_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_float64: {
+			D4Attribute *a = new D4Attribute(name, attr_float32_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_string: {
+			D4Attribute *a = new D4Attribute(name, attr_str_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_url: {
+			D4Attribute *a = new D4Attribute(name, attr_url_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		case Attr_other_xml: {
+			D4Attribute *a = new D4Attribute(name, attr_otherxml_c);
+			a->add_value_vector(*at.get_attr_vector(i));
+			add_attribute_nocopy(a);
+			break;
+		}
+		default:
+			throw InternalErr(__FILE__, __LINE__, "Unknown DAP2 attribute type in D4Attributes::copy_from_dap2()");
+		}
+	}
+}
+
+D4Attribute *
+D4Attributes::find_depth_first(const string &name, D4AttributesIter i)
+{
+    if (i == attribute_end())
+        return 0;
+    else if ((*i)->name() == name)
+        return *i;
+    else if ((*i)->type() == attr_container_c)
+        return find_depth_first(name, (*i)->attributes()->attribute_begin());
+    else
+        return find_depth_first(name, ++i);
+}
+
+D4Attribute *
+D4Attributes::find(const string &name)
+{
+    return find_depth_first(name, attribute_begin());
+}
+
+/** Return a pointer to the D4Attribute object that has the given FQN.
+ * @note A FQN for an attribute is a series of names separated by dots.
+ */
+D4Attribute *
+D4Attributes::get(const string &fqn)
+{
+    // name1.name2.name3
+    // name1
+    // name1.name2
+    size_t pos = fqn.find('.');
+    string part = fqn.substr(0, pos);
+    string rest= "";
+
+    if (pos != string::npos)
+        rest = fqn.substr(pos + 1);
+
+    DBG(cerr << "part: '" << part << "'; rest: '" << rest << "'" << endl);
+
+    if (!part.empty()) {
+        if (!rest.empty()) {
+            D4AttributesIter i = attribute_begin();
+            while (i != attribute_end()) {
+                if ((*i)->name() == part && (*i)->type() == attr_container_c)
+                    return (*i)->attributes()->get(rest);
+                ++i;
+            }
+        }
+        else {
+            D4AttributesIter i = attribute_begin();
+            while (i != attribute_end()) {
+                if ((*i)->name() == part)
+                    return (*i);
+                ++i;
+            }
+        }
+    }
+
+    return 0;
+}
+
+void
+D4Attribute::print_dap4(XMLWriter &xml) const
+{
+    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Attribute") < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write Attribute element");
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "type", (const xmlChar*) D4AttributeTypeToString(type()).c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for type");
+
+    switch (type()) {
+        case attr_container_c:
+            if (!d_attributes)
+                throw InternalErr(__FILE__, __LINE__, "Null Attribute container");
+            d_attributes->print_dap4(xml);
+            break;
+
+        case attr_otherxml_c:
+            if (num_values() != 1)
+                throw Error("OtherXML attributes cannot be vector-valued.");
+            if (xmlTextWriterWriteRaw(xml.get_writer(), (const xmlChar*) value(0).c_str()) < 0)
+                throw InternalErr(__FILE__, __LINE__, "Could not write OtherXML value");
+            break;
+
+        default: {
+            // Assume only valid types make it into instances
+            D4AttributeCIter i = d_values.begin();//value_begin();
+            while (i != d_values.end()) {
+                if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Value") < 0)
+                    throw InternalErr(__FILE__, __LINE__, "Could not write value element");
+
+                if (xmlTextWriterWriteString(xml.get_writer(), (const xmlChar*) (*i++).c_str()) < 0)
+                    throw InternalErr(__FILE__, __LINE__, "Could not write attribute value");
+
+                if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+                    throw InternalErr(__FILE__, __LINE__, "Could not end value element");
+            }
+
+            break;
+        }
+    }
+
+    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not end Attribute element");
+}
+
+void
+D4Attributes::print_dap4(XMLWriter &xml) const
+{
+    if (empty())
+        return;
+
+    D4AttributesCIter i = d_attrs.begin();
+    while (i != d_attrs.end()) {
+        (*i++)->print_dap4(xml);
+    }
+}
+
+} // namespace libdap
+
diff --git a/D4Attributes.h b/D4Attributes.h
new file mode 100644
index 0000000..1bdf320
--- /dev/null
+++ b/D4Attributes.h
@@ -0,0 +1,161 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 _d4attributes_h
+#define _d4attributes_h 1
+
+#include <string>
+#include <vector>
+
+#include "D4AttributeType.h"
+#include "XMLWriter.h"
+
+using namespace std;
+
+namespace libdap
+{
+
+class AttrTable;
+class D4Attributes;
+
+class D4Attribute {
+    string d_name;
+    D4AttributeType d_type;    // Attributes are limited to the simple types
+
+    // If d_type is attr_container_c is true, use d_attributes to read
+    // the contained attributes, otherwise use d_values to read the vector
+    // of values.
+    D4Attributes *d_attributes;
+
+    // IF d_type is attr_otherxml_c, the first string in d_values holds the
+    // XML, otherwise, the strings hold attributes of type d_type.
+    vector<string> d_values;
+
+    // perform a deep copy
+    void m_duplicate(const D4Attribute &src);
+
+public:
+    typedef vector<string>::iterator D4AttributeIter;
+    typedef vector<string>::const_iterator D4AttributeCIter;
+
+    D4Attribute() : d_name(""), d_type(attr_null_c), d_attributes(0) {}
+    D4Attribute(const string &name, D4AttributeType type)
+        : d_name(name), d_type(type), d_attributes(0) {}
+
+    D4Attribute(const D4Attribute &src);
+    ~D4Attribute();
+    D4Attribute &operator=(const D4Attribute &rhs);
+
+    string name() const { return d_name; }
+    void set_name(const string &name) { d_name = name; }
+
+    D4AttributeType type() const { return d_type; }
+    void set_type(D4AttributeType type) { d_type = type; }
+
+    void add_value(const string &value) { d_values.push_back(value); }
+    void add_value_vector(const vector<string> &values) { d_values = values; }
+
+    D4AttributeIter value_begin() { return d_values.begin(); }
+    D4AttributeIter value_end() { return d_values.end(); }
+
+    unsigned int num_values() const { return d_values.size(); }
+    string value(unsigned int i) const { return d_values[i]; }
+
+    D4Attributes *attributes();
+
+    void print_dap4(XMLWriter &xml) const;
+};
+
+class D4Attributes {
+public:
+    typedef vector<D4Attribute*>::iterator D4AttributesIter;
+    typedef vector<D4Attribute*>::const_iterator D4AttributesCIter;
+
+private:
+    vector<D4Attribute*> d_attrs;
+
+    void m_duplicate(const D4Attributes &src) {
+        D4AttributesCIter i = src.d_attrs.begin();
+        while (i != src.d_attrs.end()) {
+            d_attrs.push_back(new D4Attribute(**i++));    // deep copy
+        }
+    }
+
+    D4Attribute *find_depth_first(const string &name, D4AttributesIter i);
+
+public:
+
+    D4Attributes() {}
+    D4Attributes(const D4Attributes &rhs) {
+        m_duplicate(rhs);
+    }
+
+    virtual ~D4Attributes() {
+        D4AttributesIter i = d_attrs.begin();
+        while(i != d_attrs.end()) {
+            delete *i++;
+        }
+    }
+
+    D4Attributes &operator=(const D4Attributes &rhs) {
+        if (this == &rhs) return *this;
+        m_duplicate(rhs);
+        return *this;
+    }
+
+    void transform_to_dap4(AttrTable &at);
+
+    bool empty() const { return d_attrs.empty(); }
+
+    void add_attribute(D4Attribute *attr) {
+        d_attrs.push_back(new D4Attribute(*attr));
+    }
+    void add_attribute_nocopy(D4Attribute *attr) {
+        d_attrs.push_back(attr);
+    }
+
+    /// Get an iterator to the start of the enumerations
+    D4AttributesIter attribute_begin() { return d_attrs.begin(); }
+
+    /// Get an iterator to the end of the enumerations
+    D4AttributesIter attribute_end() { return d_attrs.end(); }
+
+    D4Attribute *find(const string &name);
+    D4Attribute *get(const string &fqn);
+
+    // D4Attribute *find_container(const string &name);
+    // D4Attribute *get_container(const string &fqn);
+
+    // Might add erase()
+
+    void print_dap4(XMLWriter &xml) const;
+};
+
+string D4AttributeTypeToString(D4AttributeType at);
+D4AttributeType StringToD4AttributeType(string s);
+
+} // namespace libdap
+
+#endif // _d4attributes_h
diff --git a/D4BaseTypeFactory.cc b/D4BaseTypeFactory.cc
index b54c67f..8e29232 100644
--- a/D4BaseTypeFactory.cc
+++ b/D4BaseTypeFactory.cc
@@ -23,10 +23,12 @@
 //
 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
+#include "config.h"
 
 #include <string>
 
 #include "BaseType.h"
+#include "Type.h"
 
 #include "Byte.h"
 #include "Int8.h"
@@ -34,19 +36,24 @@
 #include "UInt16.h"
 #include "Int32.h"
 #include "UInt32.h"
+
 #include "Int64.h"
 #include "UInt64.h"
 
 #include "Float32.h"
 #include "Float64.h"
 
+#include "D4Enum.h"
+
 #include "Str.h"
 #include "Url.h"
 
+#include "D4Opaque.h"
+
 #include "Array.h"
+
 #include "Structure.h"
-#include "Sequence.h"
-#include "Grid.h"
+#include "D4Sequence.h"
 
 #include "D4Group.h"
 
@@ -55,12 +62,81 @@
 
 namespace libdap {
 
+BaseType *D4BaseTypeFactory::NewVariable(Type t, const string &name) const
+{
+    switch (t) {
+        case dods_byte_c:
+            return NewByte(name);
+        case dods_char_c:
+        	return NewChar(name);
+        case dods_uint8_c:
+            return NewUInt8(name);
+        case dods_int8_c:
+            return NewInt8(name);
+
+        case dods_int16_c:
+            return NewInt16(name);
+        case dods_uint16_c:
+            return NewUInt16(name);
+        case dods_int32_c:
+            return NewInt32(name);
+        case dods_uint32_c:
+            return NewUInt32(name);
+
+        case dods_int64_c:
+            return NewInt64(name);
+        case dods_uint64_c:
+            return NewUInt64(name);
+
+        case dods_float32_c:
+            return NewFloat32(name);
+        case dods_float64_c:
+            return NewFloat64(name);
+
+        case dods_enum_c:
+            return NewEnum(name);
+
+        case dods_str_c:
+            return NewStr(name);
+        case dods_url_c:
+            return NewURL(name);
+
+        case dods_opaque_c:
+            return NewOpaque(name);
+
+        case dods_structure_c:
+            return NewStructure(name);
+
+        case dods_sequence_c:
+            return NewD4Sequence(name);
+
+        case dods_array_c:
+            return NewArray(name);
+
+        case dods_group_c:
+            return NewGroup(name);
+
+        default:
+            throw InternalErr(__FILE__, __LINE__, "Unimplemented type in DAP4");
+    }
+}
+
 Byte *
 D4BaseTypeFactory::NewByte(const string &n) const
 {
     return new Byte(n);
 }
 
+// Use the type constants specific to Char and UInt8 so the print reps will
+// match the server's idea of the types.
+Byte *
+D4BaseTypeFactory::NewChar(const string &n) const
+{
+    Byte *b = new Byte(n);
+    b->set_type(dods_char_c);
+    return b;
+}
+
 Byte *
 D4BaseTypeFactory::NewUInt8(const string &n) const
 {
@@ -125,6 +201,20 @@ D4BaseTypeFactory::NewFloat64(const string &n) const
     return new Float64(n);
 }
 
+/**
+ * Enums need a name and the name of an enumeration that was defined by the
+ * dataset. If the later is not known, it must be set before the enum is used.
+ * @param name
+ * @param enum_name
+ * @return
+ */
+D4Enum *
+D4BaseTypeFactory::NewEnum(const string &name, Type type) const
+{
+    return new D4Enum(name, type);
+}
+
+
 Str *
 D4BaseTypeFactory::NewStr(const string &n) const
 {
@@ -137,18 +227,24 @@ D4BaseTypeFactory::NewUrl(const string &n) const
     return new Url(n);
 }
 
+D4Opaque *
+D4BaseTypeFactory::NewOpaque(const string &n) const
+{
+    return new D4Opaque(n);
+}
+
+/** Note that this method is called NewURL - URL in caps.
+ */
 Url *
 D4BaseTypeFactory::NewURL(const string &n) const
 {
-    Url *u = new Url(n);
-    u->set_type(dods_url4_c);
-    return u;
+    return new Url(n);
 }
 
 Array *
-D4BaseTypeFactory::NewArray(const string &n , BaseType *v) const
+D4BaseTypeFactory::NewArray(const string &n, BaseType *v) const
 {
-    return new Array(n, v);
+	return new Array(n, v, true /* is_dap4 */);
 }
 
 Structure *
@@ -157,23 +253,16 @@ D4BaseTypeFactory::NewStructure(const string &n) const
     return new Structure(n);
 }
 
-D4Group *
-D4BaseTypeFactory::NewGroup(const string &n) const
+D4Sequence *
+D4BaseTypeFactory::NewD4Sequence(const string &n) const
 {
-    return new D4Group(n);
-}
-
-Sequence *
-D4BaseTypeFactory::NewSequence(const string &n) const
-{
-    DBG(cerr << "Inside DAP4BaseTypeFactory::NewSequence" << endl);
-    return new Sequence(n);
+	return new D4Sequence(n);
 }
 
-Grid *
-D4BaseTypeFactory::NewGrid(const string &n) const
+D4Group *
+D4BaseTypeFactory::NewGroup(const string &n) const
 {
-    return new Grid(n);
+    return new D4Group(n);
 }
 
 } // namespace libdap
diff --git a/D4BaseTypeFactory.h b/D4BaseTypeFactory.h
index b420f5a..b302c16 100644
--- a/D4BaseTypeFactory.h
+++ b/D4BaseTypeFactory.h
@@ -29,6 +29,7 @@
 #include <string>
 
 #include "BaseTypeFactory.h"
+#include "Type.h"
 
 // Class declarations; Make sure to include the corresponding headers in the
 // implementation file.
@@ -51,10 +52,13 @@ class Float64;
 class Str;
 class Url;
 
+class D4Enum;
+class D4Opaque;
+
 class Array;
+
 class Structure;
-class Sequence;
-class Grid;
+class D4Sequence;
 
 class D4Group;
 
@@ -73,36 +77,45 @@ public:
     virtual ~D4BaseTypeFactory()
     {}
 
+    virtual BaseType *NewVariable(Type t, const string &name) const;
+
+    virtual BaseTypeFactory *ptr_duplicate() const {
+        return new D4BaseTypeFactory;
+    }
+
     virtual Byte *NewByte(const string &n = "") const;
+
+    // The Int8 types are new for DAP4
     virtual Int8 *NewInt8(const string &n = "") const;
+    virtual Byte *NewChar(const string &n = "") const;
     virtual Byte *NewUInt8(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;
 
+    // New for DAP4
     virtual Int64 *NewInt64(const string &n = "") const;
     virtual UInt64 *NewUInt64(const string &n = "") const;
 
     virtual Float32 *NewFloat32(const string &n = "") const;
     virtual Float64 *NewFloat64(const string &n = "") const;
 
+    virtual D4Enum *NewEnum(const string &n = "", Type type = dods_null_c) const;
+
     virtual Str *NewStr(const string &n = "") const;
     virtual Url *NewUrl(const string &n = "") const;
     virtual Url *NewURL(const string &n = "") const;
 
-    // FIXME Define these
-#if 0
-    virtual Opaque *NewOpaque(const string &n = "") const;
-    virtual Enumeration *NewEnumeration(const string &n = "") const;
-#endif
+    virtual D4Opaque *NewOpaque(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;
-#if 1
+    virtual D4Sequence *NewD4Sequence(const string &n = "") const;
+
     virtual D4Group *NewGroup(const string &n = "") const;
-#endif
-    virtual Array *NewArray(const string &n = "", BaseType *v = 0) const;
-    virtual Grid *NewGrid(const string &n = "") const;
 };
 
 } // namespace libdap
diff --git a/Connect.cc b/D4Connect.cc
similarity index 54%
copy from Connect.cc
copy to D4Connect.cc
index 8ea727a..2837f48 100644
--- a/Connect.cc
+++ b/D4Connect.cc
@@ -34,228 +34,163 @@
 
 #include "config.h"
 
-//#define DODS_DEBUG
-#define FILE_UN_MARSHALLER 1
-
+#include <cassert>
 #include <cstring>
-#include <fstream>
-#include <algorithm>
 
-#include "debug.h"
-#include "DataDDS.h"
-#include "Connect.h"
+#include "D4Connect.h"
+#include "HTTPConnect.h"
+#include "Response.h"
+#include "DMR.h"
+#include "D4Group.h"
+
+#include "D4ParserSax2.h"
+#include "chunked_stream.h"
+#include "chunked_istream.h"
+#include "D4StreamUnMarshaller.h"
+
 #include "escaping.h"
-//#include "RCReader.h"
-#include "DDXParserSAX2.h"
-#if FILE_UN_MARSHALLER
-#include "XDRFileUnMarshaller.h"
-#else
-#include "fdiostream.h"
-#include "XDRStreamUnMarshaller.h"
-#endif
 #include "mime_util.h"
+#include "debug.h"
 
-using std::cerr;
-using std::endl;
-using std::ifstream;
-using std::ofstream;
-using std::min;
+using namespace std;
 
 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)
+    exists to eliminate duplication of code. */
+void D4Connect::process_dmr(DMR &dmr, Response &rs)
 {
-    DBG(cerr << "Entering Connect::process_data" << endl);
-
-    data.set_version(rs->get_version());
-    data.set_protocol(rs->get_protocol());
+	DBG(cerr << "Entering D4Connect::process_dmr" << endl);
 
-    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_UN_MARSHALLER
-            XDRFileUnMarshaller um(rs->get_stream());
-#else
-        fpistream in ( rs->get_stream() );
-            XDRStreamUnMarshaller um( in );
-#endif
-            for (DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
-                (*i)->deserialize(um, &data);
-            }
-            return;
-        }
+	dmr.set_dap_version(rs.get_protocol());
 
-        case dods_data:
-        default: {
-            // Parse the DDS; throw an exception on error.
-            data.parse(rs->get_stream());
-#if FILE_UN_MARSHALLER
-            XDRFileUnMarshaller um(rs->get_stream());
-#else
-            fpistream in ( rs->get_stream() );
-            XDRStreamUnMarshaller um( in );
+	DBG(cerr << "Entering process_data: d_stream = " << rs << endl);
+	switch (rs.get_type()) {
+	case dap4_error: {
+#if 0
+		Error e;
+		if (!e.parse(rs.get_stream()))
+			throw InternalErr(__FILE__, __LINE__, "Could not parse the Error object returned by the server!");
+		throw e;
 #endif
-            // Load the DDS with data.
-            for (DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
-                (*i)->deserialize(um, &data);
-            }
-            return;
-        }
-    }
+		throw InternalErr(__FILE__, __LINE__, "DAP4 errors not processed yet: FIXME!");
+	}
+
+	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_dmr: {
+		// parse the DMR
+		try {
+			D4ParserSax2 parser;
+			parser.intern(*rs.get_cpp_stream(), &dmr, /*debug*/false);
+		}
+		catch (Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			return;
+		}
+		catch (std::exception &e) {
+			cerr << "Exception: " << e.what() << endl;
+			return;
+		}
+		catch (...) {
+			cerr << "Exception: unknown error" << endl;
+			return;
+		}
+
+		return;
+	}
+
+	default:
+		throw Error("Unknown response type");
+	}
 }
 
 /** This private method process data from both local and remote sources. It
     exists to eliminate duplication of code. */
-void
-Connect::process_data(DDS &data, Response *rs)
+void D4Connect::process_data(DMR &data, Response &rs)
 {
-    DBG(cerr << "Entering Connect::process_data" << endl);
+	DBG(cerr << "Entering D4Connect::process_data" << endl);
 
-#if 0
-    data.set_version(rs->get_version());
-    data.set_protocol(rs->get_protocol());
-#endif
-    // TODO is this the correct info?
-    data.set_dap_version(rs->get_protocol());
+	assert(rs.get_cpp_stream());	// DAP4 code uses cpp streams
 
-    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;
-        }
+	data.set_dap_version(rs.get_protocol());
 
-    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_UN_MARSHALLER
-        XDRFileUnMarshaller um( rs->get_stream() ) ;
-#else
-        fpistream in ( rs->get_stream() );
-        XDRStreamUnMarshaller um( in ) ;
-#endif
+	DBG(cerr << "Entering process_data: d_stream = " << rs << endl);
+	switch (rs.get_type()) {
+	case dap4_error: {
 #if 0
-        try {
+		Error e;
+		if (!e.parse(rs.get_cpp_stream()))
+			throw InternalErr(__FILE__, __LINE__, "Could not parse the Error object returned by the server!");
+		throw e;
 #endif
-            for (DDS::Vars_iter i = data.var_begin(); i != data.var_end();
-                     i++) {
-                    (*i)->deserialize(um, &data);
-                }
-#if 0
-            }
-            catch (Error &e) {
-                throw ;
-            }
+		throw InternalErr(__FILE__, __LINE__, "DAP4 errors not processed yet: FIXME!");
+	}
+
+	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: {
+#if BYTE_ORDER_PREFIX
+		// Read the byte-order byte; used later on
+		char byte_order;
+		*rs.get_cpp_stream() >> byte_order;
+		//if (debug) cerr << "Byte order: " << ((byte_order) ? "big endian" : "little endian") << endl;
 #endif
-            return;
-        }
-
-    case dods_data:
-    default: {
-            // Parse the DDS; throw an exception on error.
-            data.parse(rs->get_stream());
-#if FILE_UN_MARSHALLER
-            XDRFileUnMarshaller um( rs->get_stream() ) ;
+		// get a chunked input stream
+#if BYTE_ORDER_PREFIX
+		chunked_istream cis(*rs.get_cpp_stream(), 1024, byte_order);
 #else
-           fpistream in ( rs->get_stream() );
-        XDRStreamUnMarshaller um( in ) ;
-#endif
-            // Load the DDS with data.
-#if 0
-            try {
+		chunked_istream cis(*(rs.get_cpp_stream()), CHUNK_SIZE);
 #endif
-                for (DDS::Vars_iter i = data.var_begin(); i != data.var_end();
-                     i++) {
-                    (*i)->deserialize(um, &data);
-                }
-#if 0
-            }
-            catch (Error &e) {
-                throw ;
-            }
+		// parse the DMR, stopping when the boundary is found.
+		try {
+			// force chunk read
+			// get chunk size
+			int chunk_size = cis.read_next_chunk();
+			// get chunk
+			char chunk[chunk_size];
+			cis.read(chunk, chunk_size);
+			// parse char * with given size
+			D4ParserSax2 parser;
+			// '-2' to discard the CRLF pair
+			parser.intern(chunk, chunk_size - 2, &data, /*debug*/false);
+		}
+		catch (Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			return;
+		}
+		catch (std::exception &e) {
+			cerr << "Exception: " << e.what() << endl;
+			return;
+		}
+		catch (...) {
+			cerr << "Exception: unknown error" << endl;
+			return;
+		}
+
+#if BYTE_ORDER_PREFIX
+		D4StreamUnMarshaller um(cis, byte_order);
+#else
+		D4StreamUnMarshaller um(cis, cis.twiddle_bytes());
 #endif
-            return;
-        }
-    }
-}
+		data.root()->deserialize(um, data);
 
-// 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
+		return;
+	}
+
+	default:
+		throw Error("Unknown response type");
+	}
+}
 
 /** Use when you cannot use libcurl.
 
@@ -263,43 +198,42 @@ Connect::process_data(DDS &data, Response *rs)
  (\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)
+void D4Connect::parse_mime(Response &rs)
 {
-    rs->set_version("dods/0.0"); // initial value; for backward compatibility.
-    rs->set_protocol("2.0");
+    rs.set_version("dods/0.0"); // initial value; for backward compatibility.
+    rs.set_protocol("2.0");
 
-    FILE *data_source = rs->get_stream();
+    istream &data_source = *rs.get_cpp_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:") {
+        if (header == "content-description") {
             DBG(cout << header << ": " << value << endl);
-            rs->set_type(get_description_type(value));
+            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") {
+        else if (header == "xdods-server" && rs.get_version() == "dods/0.0") {
             DBG(cout << header << ": " << value << endl);
-            rs->set_version(value);
+            rs.set_version(value);
         }
         // This trumps 'xdods-server' and 'server'
-        else if (header == "xopendap-server:") {
+        else if (header == "xopendap-server") {
             DBG(cout << header << ": " << value << endl);
-            rs->set_version(value);
+            rs.set_version(value);
         }
-        else if (header == "xdap:") {
+        else if (header == "xdap") {
             DBG(cout << header << ": " << value << endl);
-            rs->set_protocol(value);
+            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:") {
+        else if (rs.get_version() == "dods/0.0" && header == "server") {
             DBG(cout << header << ": " << value << endl);
-            rs->set_version(value);
+            rs.set_version(value);
         }
 
         mime = get_next_mime_header(data_source);
@@ -308,70 +242,168 @@ void Connect::parse_mime(Response *rs)
 
 // public mfuncs
 
-/** The Connect constructor requires a <tt>name</tt>, which is the URL to
- which the connection is to be made.
+/** The D4Connect constructor requires a URL or local file.
 
  @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")
+D4Connect::D4Connect(const string &url, string uname, string password) :
+        d_http(0), d_local(false), d_URL(""), d_dap4ce(""), d_server("unknown"), d_protocol("4.0")
 {
-    string name = prune_spaces(n);
+    string name = prune_spaces(url);
 
     // 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());
+        d_http->set_use_cpp_streams(true);
 
         // 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 = "";
-            }
+            d_URL = name.substr(0, dotpos);
+            d_dap4ce = name.substr(dotpos + 1);
         }
         else {
-            _URL = name;
-            _proj = "";
-            _sel = "";
+            d_URL = name;
         }
-
-        _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
+        d_local = true; // local in this case means non-DAP
     }
 
     set_credentials(uname, password);
 }
 
-Connect::~Connect()
+D4Connect::~D4Connect()
 {
-    DBG2(cerr << "Entering the Connect dtor" << endl);
+	if (d_http) delete d_http;
+}
 
-    if (d_http)
-        delete d_http;
-    d_http = 0;
+void D4Connect::request_dmr(DMR &dmr, const string expr)
+{
+	string url = d_URL + ".dmr" + "?" + id2www_ce(d_dap4ce + expr);
+
+	Response *rs = 0;
+	try {
+		rs = d_http->fetch_url(url);
+
+		d_server = rs->get_version();
+		d_protocol = rs->get_protocol();
+
+		switch (rs->get_type()) {
+		case unknown_type:			// FIXME Pure hackery!
+		    cerr << "Response type unknown, assuming it's a DMR response." << endl;
+		    /* no break */
+		case dap4_dmr: {
+			D4ParserSax2 parser;
+			parser.intern(*rs->get_cpp_stream(), &dmr, false /* debug */);
+			break;
+		}
+
+		case dap4_error:
+			throw InternalErr(__FILE__, __LINE__, "DAP4 errors are not processed yet.");
+
+		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.
+			throw InternalErr(__FILE__, __LINE__, "Web error found where it should never be.");
+			break;
+
+		default:
+			throw InternalErr(__FILE__, __LINE__, "Response type not handled (got "
+					+ long_to_string(rs->get_type()) + ").");
+		}
+	}
+	catch (...) {
+		delete rs;
+		throw;
+	}
+
+	delete rs;
+}
+
+void D4Connect::request_dap4_data(DMR &dmr, const string expr)
+{
+    string url = d_URL + ".dap" + "?" + id2www_ce(d_dap4ce + expr);
+
+    Response *rs = 0;
+    try {
+        rs = d_http->fetch_url(url);
+
+        d_server = rs->get_version();
+        d_protocol = rs->get_protocol();
+
+        switch (rs->get_type()) {
+        case unknown_type:          // FIXME Pure hackery!
+            cerr << "Response type unknown, assuming it's a DAP4 Data response." << endl;
+            /* no break */
+        case dap4_data: {
+            // TODO Move to a function 11/9/13 process_data()???
+#if BYTE_ORDER_PREFIX
+            istream &in = *rs->get_cpp_stream();
+            // Read the byte-order byte; used later on
+            char byte_order;
+            in >> byte_order;
+#endif
+
+            // get a chunked input stream
+#if BYTE_ORDER_PREFIX
+		chunked_istream cis(*(rs->get_cpp_stream()), 1024, byte_order);
+#else
+		chunked_istream cis(*(rs->get_cpp_stream()), CHUNK_SIZE);
+#endif
+
+            // parse the DMR, stopping when the boundary is found.
+
+            // force chunk read
+            // get chunk size
+            int chunk_size = cis.read_next_chunk();
+            // get chunk
+            char chunk[chunk_size];
+            cis.read(chunk, chunk_size);
+            // parse char * with given size
+            D4ParserSax2 parser;
+            // '-2' to discard the CRLF pair
+            parser.intern(chunk, chunk_size - 2, &dmr, false /*debug*/);
+
+            // Read data and store in the DMR
+#if BYTE_ORDER_PREFIX
+            D4StreamUnMarshaller um(cis, byte_order);
+#else
+            D4StreamUnMarshaller um(cis, cis.twiddle_bytes());
+#endif
+            dmr.root()->deserialize(um, dmr);
+
+            break;
+        }
 
-    DBG2(cerr << "Leaving the Connect dtor" << endl);
+        case dap4_error:
+            throw InternalErr(__FILE__, __LINE__, "DAP4 errors are not processed yet.");
+
+        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.
+            throw InternalErr(__FILE__, __LINE__, "Web error found where it should never be.");
+            break;
+
+        default:
+            throw InternalErr(__FILE__, __LINE__, "Response type not handled (got "
+                    + long_to_string(rs->get_type()) + ").");
+        }
+    }
+    catch (...) {
+        delete rs;
+        throw;
+    }
+
+    delete rs;
 }
 
+#if 0
 /** Get version information from the server. This is a new method which will
  ease the transition to DAP 4.
 
@@ -379,7 +411,7 @@ Connect::~Connect()
 
  @return The DAP version string.
  @see request_protocol() */
-string Connect::request_version()
+string D4D4Connect::request_version()
 {
     string version_url = _URL + ".ver";
     if (_proj.length() + _sel.length())
@@ -391,15 +423,13 @@ string Connect::request_version()
     }
     catch (Error &e) {
         delete rs;
-        rs = 0;
         throw;
     }
 
-    d_version = rs->get_version();
-    d_protocol = rs->get_protocol();
+    d_server = rs.get_server();
+    d_protocol = rs.get_protocol();
 
     delete rs;
-    rs = 0;
 
     return d_version;
 }
@@ -415,7 +445,7 @@ string Connect::request_version()
  response (e.g., from the last DDX response returned by the server).
 
  @return The DAP protocol version string. */
-string Connect::request_protocol()
+string D4D4Connect::request_protocol()
 {
     string version_url = _URL + ".ver";
     if (_proj.length() + _sel.length())
@@ -431,8 +461,8 @@ string Connect::request_protocol()
         throw;
     }
 
-    d_version = rs->get_version();
-    d_protocol = rs->get_protocol();
+    d_version = rs.get_version();
+    d_protocol = rs.get_protocol();
 
     delete rs;
     rs = 0;
@@ -447,7 +477,7 @@ string Connect::request_protocol()
 
  @brief Get the DAS from a server.
  @param das Result. */
-void Connect::request_das(DAS &das)
+void D4Connect::request_das(DAS &das)
 {
     string das_url = _URL + ".das";
     if (_proj.length() + _sel.length())
@@ -463,13 +493,13 @@ void Connect::request_das(DAS &das)
         throw;
     }
 
-    d_version = rs->get_version();
-    d_protocol = rs->get_protocol();
+    d_version = rs.get_version();
+    d_protocol = rs.get_protocol();
 
-    switch (rs->get_type()) {
+    switch (rs.get_type()) {
         case dods_error: {
             Error e;
-            if (!e.parse(rs->get_stream())) {
+            if (!e.parse(rs.get_stream())) {
                 delete rs;
                 rs = 0;
                 throw InternalErr(__FILE__, __LINE__, "Could not parse error returned from server.");
@@ -488,7 +518,7 @@ void Connect::request_das(DAS &das)
         default:
             // DAS::parse throws an exception on error.
             try {
-                das.parse(rs->get_stream()); // read and parse the das from a file
+                das.parse(rs.get_stream()); // read and parse the das from a file
             }
             catch (Error &e) {
                 delete rs;
@@ -513,7 +543,7 @@ void Connect::request_das(DAS &das)
 
  @brief Get the DAS from a server.
  @param das Result. */
-void Connect::request_das_url(DAS &das)
+void D4Connect::request_das_url(DAS &das)
 {
     string use_url = _URL + "?" + _proj + _sel;
     Response *rs = 0;
@@ -526,13 +556,13 @@ void Connect::request_das_url(DAS &das)
         throw;
     }
 
-    d_version = rs->get_version();
-    d_protocol = rs->get_protocol();
+    d_version = rs.get_version();
+    d_protocol = rs.get_protocol();
 
-    switch (rs->get_type()) {
+    switch (rs.get_type()) {
         case dods_error: {
             Error e;
-            if (!e.parse(rs->get_stream())) {
+            if (!e.parse(rs.get_stream())) {
                 delete rs;
                 rs = 0;
                 throw InternalErr(__FILE__, __LINE__, "Could not parse error returned from server.");
@@ -551,7 +581,7 @@ void Connect::request_das_url(DAS &das)
         default:
             // DAS::parse throws an exception on error.
             try {
-                das.parse(rs->get_stream()); // read and parse the das from a file
+                das.parse(rs.get_stream()); // read and parse the das from a file
             }
             catch (Error &e) {
                 delete rs;
@@ -579,7 +609,7 @@ void Connect::request_das_url(DAS &das)
  @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)
+void D4Connect::request_dds(DDS &dds, string expr)
 {
     string proj, sel;
     string::size_type dotpos = expr.find('&');
@@ -604,13 +634,13 @@ void Connect::request_dds(DDS &dds, string expr)
         throw;
     }
 
-    d_version = rs->get_version();
-    d_protocol = rs->get_protocol();
+    d_version = rs.get_version();
+    d_protocol = rs.get_protocol();
 
-    switch (rs->get_type()) {
+    switch (rs.get_type()) {
         case dods_error: {
             Error e;
-            if (!e.parse(rs->get_stream())) {
+            if (!e.parse(rs.get_stream())) {
                 delete rs;
                 rs = 0;
                 throw InternalErr(__FILE__, __LINE__, "Could not parse error returned from server.");
@@ -629,7 +659,7 @@ void Connect::request_dds(DDS &dds, string expr)
         default:
             // DDS::prase throws an exception on error.
             try {
-                dds.parse(rs->get_stream()); // read and parse the dds from a file
+                dds.parse(rs.get_stream()); // read and parse the dds from a file
             }
             catch (Error &e) {
                 delete rs;
@@ -659,7 +689,7 @@ void Connect::request_dds(DDS &dds, string expr)
 
  @brief Get the DDS from a server.
  @param dds Result. */
-void Connect::request_dds_url(DDS &dds)
+void D4Connect::request_dds_url(DDS &dds)
 {
     string use_url = _URL + "?" + _proj + _sel;
     Response *rs = 0;
@@ -672,13 +702,13 @@ void Connect::request_dds_url(DDS &dds)
         throw;
     }
 
-    d_version = rs->get_version();
-    d_protocol = rs->get_protocol();
+    d_version = rs.get_version();
+    d_protocol = rs.get_protocol();
 
-    switch (rs->get_type()) {
+    switch (rs.get_type()) {
         case dods_error: {
             Error e;
-            if (!e.parse(rs->get_stream())) {
+            if (!e.parse(rs.get_stream())) {
                 delete rs;
                 rs = 0;
                 throw InternalErr(__FILE__, __LINE__, "Could not parse error returned from server.");
@@ -697,7 +727,7 @@ void Connect::request_dds_url(DDS &dds)
         default:
             // DDS::prase throws an exception on error.
             try {
-                dds.parse(rs->get_stream()); // read and parse the dds from a file
+                dds.parse(rs.get_stream()); // read and parse the dds from a file
             }
             catch (Error &e) {
                 delete rs;
@@ -722,7 +752,7 @@ void Connect::request_dds_url(DDS &dds)
  @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)
+void D4Connect::request_ddx(DDS &dds, string expr)
 {
     string proj, sel;
     string::size_type dotpos = expr.find('&');
@@ -747,13 +777,13 @@ void Connect::request_ddx(DDS &dds, string expr)
         throw;
     }
 
-    d_version = rs->get_version();
-    d_protocol = rs->get_protocol();
+    d_version = rs.get_version();
+    d_protocol = rs.get_protocol();
 
-    switch (rs->get_type()) {
+    switch (rs.get_type()) {
         case dods_error: {
             Error e;
-            if (!e.parse(rs->get_stream())) {
+            if (!e.parse(rs.get_stream())) {
                 delete rs;
                 rs = 0;
                 throw InternalErr(__FILE__, __LINE__, "Could not parse error returned from server.");
@@ -768,13 +798,13 @@ void Connect::request_ddx(DDS &dds, string expr)
             // (called by fetch_url) and result in a thrown Error object.
             break;
 
-        case dap4_ddx:
+        case dods_ddx:
         case dods_ddx:
             try {
                 string blob;
 
                 DDXParser ddxp(dds.get_factory());
-                ddxp.intern_stream(rs->get_stream(), &dds, blob);
+                ddxp.intern_stream(rs.get_stream(), &dds, blob);
             }
             catch (Error &e) {
                 delete rs;
@@ -790,7 +820,7 @@ void Connect::request_ddx(DDS &dds, string expr)
                     "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())
+                            + 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.");
@@ -801,8 +831,8 @@ configured, or that the URL has changed.");
 }
 
 /** @brief The 'url' version of request_ddx
- @see Connect::request_ddx. */
-void Connect::request_ddx_url(DDS &dds)
+ @see D4Connect::request_ddx. */
+void D4Connect::request_ddx_url(DDS &dds)
 {
     string use_url = _URL + "?" + _proj + _sel;
 
@@ -816,13 +846,13 @@ void Connect::request_ddx_url(DDS &dds)
         throw;
     }
 
-    d_version = rs->get_version();
-    d_protocol = rs->get_protocol();
+    d_version = rs.get_version();
+    d_protocol = rs.get_protocol();
 
-    switch (rs->get_type()) {
+    switch (rs.get_type()) {
         case dods_error: {
             Error e;
-            if (!e.parse(rs->get_stream())) {
+            if (!e.parse(rs.get_stream())) {
                 delete rs;
                 rs = 0;
                 throw InternalErr(__FILE__, __LINE__, "Could not parse error returned from server.");
@@ -837,13 +867,13 @@ void Connect::request_ddx_url(DDS &dds)
             // (called by fetch_url) and result in a thrown Error object.
             break;
 
-        case dap4_ddx:
+        case dods_ddx:
         case dods_ddx:
             try {
                 string blob;
 
                 DDXParser ddxp(dds.get_factory());
-                ddxp.intern_stream(rs->get_stream(), &dds, blob);
+                ddxp.intern_stream(rs.get_stream(), &dds, blob);
             }
             catch (Error &e) {
                 delete rs;
@@ -859,7 +889,7 @@ void Connect::request_ddx_url(DDS &dds)
                     "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())
+                            + 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.");
@@ -884,7 +914,7 @@ configured, or that the URL has changed.");
  @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)
+void D4Connect::request_data(DataDDS &data, string expr)
 {
     string proj, sel;
     string::size_type dotpos = expr.find('&');
@@ -904,8 +934,8 @@ void Connect::request_data(DataDDS &data, string expr)
     try {
         rs = d_http->fetch_url(data_url);
 
-        d_version = rs->get_version();
-        d_protocol = rs->get_protocol();
+        d_version = rs.get_version();
+        d_protocol = rs.get_protocol();
 
         process_data(data, rs);
         delete rs;
@@ -935,7 +965,7 @@ void Connect::request_data(DataDDS &data, string expr)
 
  @brief Get the DAS from a server.
  @param data Result. */
-void Connect::request_data_url(DataDDS &data)
+void D4Connect::request_data_url(DataDDS &data)
 {
     string use_url = _URL + "?" + _proj + _sel;
     Response *rs = 0;
@@ -943,8 +973,8 @@ void Connect::request_data_url(DataDDS &data)
     try {
         rs = d_http->fetch_url(use_url);
 
-        d_version = rs->get_version();
-        d_protocol = rs->get_protocol();
+        d_version = rs.get_version();
+        d_protocol = rs.get_protocol();
 
         process_data(data, rs);
         delete rs;
@@ -957,7 +987,7 @@ void Connect::request_data_url(DataDDS &data)
     }
 }
 
-void Connect::request_data_ddx(DataDDS &data, string expr)
+void D4Connect::request_data_ddx(DataDDS &data, string expr)
 {
     string proj, sel;
     string::size_type dotpos = expr.find('&');
@@ -977,8 +1007,8 @@ void Connect::request_data_ddx(DataDDS &data, string expr)
     try {
         rs = d_http->fetch_url(data_url);
 
-        d_version = rs->get_version();
-        d_protocol = rs->get_protocol();
+        d_version = rs.get_version();
+        d_protocol = rs.get_protocol();
 
         process_data(data, rs);
         delete rs;
@@ -991,7 +1021,7 @@ void Connect::request_data_ddx(DataDDS &data, string expr)
     }
 }
 
-void Connect::request_data_ddx_url(DataDDS &data)
+void D4Connect::request_data_ddx_url(DataDDS &data)
 {
     string use_url = _URL + "?" + _proj + _sel;
     Response *rs = 0;
@@ -999,8 +1029,8 @@ void Connect::request_data_ddx_url(DataDDS &data)
     try {
         rs = d_http->fetch_url(use_url);
 
-        d_version = rs->get_version();
-        d_protocol = rs->get_protocol();
+        d_version = rs.get_version();
+        d_protocol = rs.get_protocol();
 
         process_data(data, rs);
         delete rs;
@@ -1012,177 +1042,61 @@ void Connect::request_data_ddx_url(DataDDS &data)
         throw;
     }
 }
+#endif
 
-/** @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);
-}
 void
-Connect::read_data(DDS &data, Response *rs)
+D4Connect::read_dmr(DMR &dmr, 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);
+    if (rs.get_type() == unknown_type)
+        throw Error("Unknown response type.");
 
-    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());
+    read_dmr_no_mime(dmr, rs);
 }
 
-/** @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.");
-    }
-}
-void Connect::read_data_no_mime(DDS &data, Response *rs)
+void
+D4Connect::read_dmr_no_mime(DMR &dmr, 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();
-        // TODO should check to see if this hack is a correct replacement
-        // for get_protocol from DataDDS
-        d_protocol = data.get_dap_version();
+	// Assume callers know what they are doing
+    if (rs.get_type() == unknown_type)
+        rs.set_type(dap4_dmr);
+
+    switch (rs.get_type()) {
+    case dap4_dmr:
+        process_dmr(dmr, rs);
+        d_server = rs.get_version();
+        d_protocol = dmr.dap_version();
         break;
     default:
-        throw InternalErr(__FILE__, __LINE__, "Should have been a DataDDS or DataDDX.");
+        throw Error("Expected a DAP4 DMR response.");
     }
 }
 
-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)
+void
+D4Connect::read_data(DMR &data, Response &rs)
 {
-    if (_local)
-        throw InternalErr(__FILE__, __LINE__, "URL(): This call is only valid for a DAP data source.");
+    parse_mime(rs);
+    if (rs.get_type() == unknown_type)
+        throw Error("Unknown response type.");
 
-    if (ce)
-        return _URL + "?" + _proj + _sel;
-    else
-        return _URL;
+    read_data_no_mime(data, rs);
 }
 
-/** 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()
+void D4Connect::read_data_no_mime(DMR &data, Response &rs)
 {
-    if (_local)
-        throw InternalErr(__FILE__, __LINE__, "CE(): This call is only valid for a DAP data source.");
+	// Assume callers know what they are doing
+    if (rs.get_type() == unknown_type)
+        rs.set_type(dap4_data);
 
-    return _proj + _sel;
+    switch (rs.get_type()) {
+    case dap4_data:
+        process_data(data, rs);
+        d_server = rs.get_version();
+        d_protocol = data.dap_version();
+        break;
+    default:
+        throw Error("Expected a DAP4 Data response.");
+    }
 }
 
 /** @brief Set the credentials for responding to challenges while dereferencing
@@ -1190,7 +1104,7 @@ string Connect::CE()
  @param u The username.
  @param p The password.
  @see extract_auth_info() */
-void Connect::set_credentials(string u, string p)
+void D4Connect::set_credentials(string u, string p)
 {
     if (d_http)
         d_http->set_credentials(u, p);
@@ -1199,7 +1113,7 @@ void Connect::set_credentials(string u, string 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)
+void D4Connect::set_accept_deflate(bool deflate)
 {
     if (d_http)
         d_http->set_accept_deflate(deflate);
@@ -1210,7 +1124,7 @@ void Connect::set_accept_deflate(bool deflate)
 
  @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)
+void D4Connect::set_xdap_protocol(int major, int minor)
 {
     if (d_http)
         d_http->set_xdap_protocol(major, minor);
@@ -1219,23 +1133,18 @@ void Connect::set_xdap_protocol(int major, int 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)
+void D4Connect::set_cache_enabled(bool cache)
 {
     if (d_http)
         d_http->set_cache_enabled(cache);
 }
 
-bool Connect::is_cache_enabled()
+bool D4Connect::is_cache_enabled()
 {
-    bool status;
-    DBG(cerr << "Entering is_cache_enabled (" << hex << d_http << dec
-            << ")... ");
     if (d_http)
-        status = d_http->is_cache_enabled();
+        return d_http->is_cache_enabled();
     else
-        status = false;
-    DBGN(cerr << "exiting" << endl);
-    return status;
+        return false;
 }
 
 } // namespace libdap
diff --git a/D4Connect.h b/D4Connect.h
new file mode 100644
index 0000000..7a5d864
--- /dev/null
+++ b/D4Connect.h
@@ -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) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _d4connect_h
+#define _d4connect_h
+
+#include <string>
+
+namespace libdap
+{
+
+class HTTPConnect;
+class DMR;
+class Response;
+
+class D4Connect
+{
+private:
+    HTTPConnect *d_http;
+
+    bool d_local;  // Is this a local connection?
+    std::string d_URL;  // URL to remote dataset (minus CE)
+    std::string d_dap4ce; 	// CE
+
+    std::string d_server; // Server implementation information (the XDAP-Server header)
+    std::string d_protocol; // DAP protocol from the server (XDAP)
+
+    void process_data(DMR &data, Response &rs);
+    void process_dmr(DMR &data, Response &rs);
+
+    // Use when you cannot use but have a complete response with MIME headers
+    void parse_mime(Response &rs);
+
+protected:
+    /** @name Suppress the C++ defaults for these. */
+    D4Connect();
+    D4Connect(const D4Connect &);
+    D4Connect &operator=(const D4Connect &);
+
+public:
+    D4Connect(const std::string &url, std::string uname = "", std::string password = "");
+
+    virtual ~D4Connect();
+
+    bool is_local() const { return d_local; }
+
+    virtual std::string URL() const { return d_URL; }
+    virtual std::string CE() const { return d_dap4ce; }
+
+    void set_credentials(std::string u, std::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 std::string "unknown." This should ultimately hold
+    the \e protocol version; it currently holds the \e implementation
+    version.
+
+        @see get_protocol()
+        @deprecated */
+    std::string get_version() { return d_server; }
+
+    /** Return the DAP protocol version of the most recent
+        response. Before a response is made, this contains the std::string "2.0."
+        */
+    std::string get_protocol() { return d_protocol; }
+
+    virtual void request_dmr(DMR &dmr, const std::string expr = "");
+    virtual void request_dap4_data(DMR &dmr, const std::string expr = "");
+#if 0
+    virtual void request_version();
+#endif
+
+    virtual void read_dmr(DMR &dmr, Response &rs);
+    virtual void read_dmr_no_mime(DMR &dmr, Response &rs);
+
+    virtual void read_data(DMR &data, Response &rs);
+    virtual void read_data_no_mime(DMR &data, Response &rs);
+};
+
+} // namespace libdap
+
+#endif // _d4connect_h
diff --git a/D4Dimensions.cc b/D4Dimensions.cc
index 7f51723..86a16cc 100644
--- a/D4Dimensions.cc
+++ b/D4Dimensions.cc
@@ -1,23 +1,142 @@
-/*
- * D4Dimensions.cc
- *
- *  Created on: Sep 26, 2012
- *      Author: jimg
- */
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 <sstream>
+
+#include "XMLWriter.h"
 #include "D4Dimensions.h"
+#include "D4Group.h"
+
+#include "Error.h"
+#include "InternalErr.h"
 
 namespace libdap {
 
-D4Dimensions::D4Dimensions()
+void
+D4Dimension::set_size(const string &size)
 {
-    // TODO Auto-generated constructor stub
+	unsigned long value = 0;
+	istringstream iss(size);
+	iss >> value;
+
+	// First test if the stream is OK, then look to see if we read all
+	// of the chars.
+	if (!iss || !iss.eof()) throw Error("Invalid value '" + size + "' passed to D4Dimension::set_size.");
+	set_size(value);
+}
+
+/**
+ * @brief Get the FQN for the dimension
+ * @return The D4Dimension as a fully qualified name.
+ */
+string
+D4Dimension::fully_qualified_name() const
+{
+	string name = d_name;
+
+	// d_parent is the D4Dimensions container and its parent is the Group where
+	// this Dimension is defined.
+	D4Group *grp = d_parent->parent();
+	while (grp) {
+		// The root group is named "/" (always); this avoids '//name'
+		name = (grp->name() == "/") ? "/" + name : grp->name() + "/" + name;
+
+		if (grp->get_parent())
+			grp = static_cast<D4Group*>(grp->get_parent());
+		else
+			grp = 0;
+	}
 
+	return name;
+}
+
+/**
+ * @brief Print the Dimension declaration.
+ * Print the Dimension in a form suitable for use in a Group definition/declaration.
+ * @see print_dap4(XMLWriter &xml, bool print_fqn)
+ * @param xml Print to this XMLWriter instance
+ */
+void
+D4Dimension::print_dap4(XMLWriter &xml) const
+{
+	if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Dimension") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write Dimension element");
+
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+#if 0
+	// Use FQNs when things are referenced, not when they are defined
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)fully_qualified_name().c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+#endif
+	ostringstream oss;
+	if (d_constrained)
+	    oss << (d_c_stop - d_c_start) / d_c_stride + 1;
+	else
+	    oss << d_size;
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "size", (const xmlChar*) oss.str().c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for size");
+
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end Dimension element");
+}
+
+// Note that in order for this to work the second argument must not be a reference.
+// jhrg 8/20/13
+static bool
+dim_name_eq(D4Dimension *d, const string name)
+{
+	return d->name() == name;
+}
+
+D4Dimension *
+D4Dimensions::find_dim(const string &name)
+{
+	D4DimensionsIter d = find_if(d_dims.begin(), d_dims.end(), bind2nd(ptr_fun(dim_name_eq), name));
+	return (d != d_dims.end()) ? *d: 0;
 }
 
-D4Dimensions::~D4Dimensions()
+void
+D4Dimensions::print_dap4(XMLWriter &xml, bool constrained) const
 {
-    // TODO Auto-generated destructor stub
+    D4DimensionsCIter i = d_dims.begin();
+    while (i != d_dims.end()) {
+#if 0
+    	if (!constrained || parent()->find_first_var_that_uses_dimension(*i))
+            (*i)->print_dap4(xml);
+#endif
+    	if (constrained) {
+    		if ((*i)->used_by_projected_var())
+    		    (*i)->print_dap4(xml);
+    	}
+    	else {
+    		(*i)->print_dap4(xml);
+    	}
+        ++i;
+    }
 }
 
 } /* namespace libdap */
diff --git a/D4Dimensions.h b/D4Dimensions.h
index c1446e1..f4eeeaf 100644
--- a/D4Dimensions.h
+++ b/D4Dimensions.h
@@ -1,9 +1,26 @@
-/*
- * D4Dimensions.h
- *
- *  Created on: Sep 26, 2012
- *      Author: jimg
- */
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 D4DIMENSIONS_H_
 #define D4DIMENSIONS_H_
@@ -11,53 +28,166 @@
 #include <string>
 #include <vector>
 
+// #include "XMLWriter.h"
+
 using namespace std;
 
 namespace libdap {
 
+class D4Group;
+class D4Dimensions;
+class XMLWriter;
+
+class D4Dimension {
+    string d_name;
+    unsigned long d_size;
+
+    D4Dimensions *d_parent;	// This is used to get the Dimensions and then the Group object
+
+    bool d_constrained;
+    unsigned long long d_c_start, d_c_stride, d_c_stop;
+
+    bool d_used_by_projected_var;
+
+public:
+    D4Dimension() : d_name(""), d_size(0),  d_parent(0), d_constrained(false), d_c_start(0), d_c_stride(0),
+            d_c_stop(0), d_used_by_projected_var(false) {}
+    D4Dimension(const string &name, unsigned long size, D4Dimensions *d = 0) : d_name(name), d_size(size), d_parent(d),
+            d_constrained(false), d_c_start(0), d_c_stride(0), d_c_stop(0), d_used_by_projected_var(false) {}
+
+    string name() const {return d_name;}
+    void set_name(const string &name) { d_name = name; }
+    string fully_qualified_name() const;
+
+    unsigned long size() const { return d_size; }
+    void set_size(unsigned long size) { d_size = size; }
+    // Because we build these in the XML parser and it's all text...
+    void set_size(const string &size);
+
+    D4Dimensions *parent() const { return d_parent; }
+    void set_parent(D4Dimensions *d) { d_parent = d; }
+
+    bool constrained() const { return d_constrained; }
+    unsigned long long c_start() const { return d_c_start; }
+    unsigned long long c_stride() const { return d_c_stride; }
+    unsigned long long c_stop() const { return d_c_stop; }
+
+    bool used_by_projected_var() const { return d_used_by_projected_var; }
+    void set_used_by_projected_var(bool state) { d_used_by_projected_var = state; }
+
+    /**
+     * Set this Shared Diemension's constraint. While an Array Dimension object uses a
+     * stop value of -1 to indicate the end of the dimension, this method does not support
+     * that; the caller will have to sort out the correct end value for 'stop'.
+     * @param start Starting index (zero-based)
+     * @param stride The stride for the slice
+     * @param stop The stopping index (never greater than size -1)
+     */
+    void set_constraint(unsigned long long start, unsigned long long stride, unsigned long long stop) {
+        d_c_start = start;
+        d_c_stride = stride;
+        d_c_stop = stop;
+        d_constrained = true;
+    }
+
+    void print_dap4(XMLWriter &xml) const;
+};
+
 /**
  * This class holds information about dimensions. This can be used to store
  * actual dimension information in an instance of BaseType and it can be
  * used to store the definition of a dimension in an instance of Group.
- *
- *
- * @todo What about storing constraint information too? Maybe we do need
- * two classes - one for defs and one for 'refs'
  */
 class D4Dimensions {
-    struct dimension {
-        string name;
-        unsigned long size;
+    vector<D4Dimension*> d_dims;
 
-        dimension(const string &n, const unsigned long s) :
-            name(n), size(s) {}
-    };
+    D4Group *d_parent;		// the group that holds this set of D4Dimensions; weak pointer, don't delete
 
-    vector<dimension> d_dims;
+protected:
+    // Note Code in Array depends on the order of these 'new' dimensions
+    // matching the 'old' dimensions they are derived from. See
+    // Array::update_dimension_pointers. jhrg 8/25/14
+    void m_duplicate(const D4Dimensions &rhs) {
+        D4DimensionsCIter i = rhs.d_dims.begin();
+        while (i != rhs.d_dims.end()) {
+            d_dims.push_back(new D4Dimension(**i++));    // deep copy
+            d_dims.back()->set_parent(this);			// Set the Dimension's parent
+        }
+
+        d_parent = rhs.d_parent;
+    }
 
 public:
-    D4Dimensions();
-    virtual ~D4Dimensions();
+    /// Iterator used for D4Dimensions
+    typedef vector<D4Dimension*>::iterator D4DimensionsIter;
+    typedef vector<D4Dimension*>::const_iterator D4DimensionsCIter;
 
-    typedef vector<dimension>::iterator D4DimensionsIter;
+    D4Dimensions() : d_parent(0) {}
+    D4Dimensions(D4Group *g) : d_parent(g) {}
+    D4Dimensions(const D4Dimensions &rhs) : d_parent(0) { m_duplicate(rhs); }
 
-    void add_dim(const string &name, const unsigned long size) {
-        d_dims.push_back(dimension(name, size));
+    virtual ~D4Dimensions() {
+        D4DimensionsIter i = d_dims.begin();
+        while (i != d_dims.end())
+            delete *i++;
     }
-    void add_dim(const string &name) {
-        d_dims.push_back(dimension(name, 0));
+
+    D4Dimensions &operator=(const D4Dimensions &rhs) {
+        if (this == &rhs) return *this;
+        m_duplicate(rhs);
+        return *this;
     }
-    void add_dim(const unsigned long size) {
-        d_dims.push_back(dimension("", size));
+
+    /// Does this D4Dimensions object actually have dimensions?
+    bool empty() const { return d_dims.empty(); }
+
+    D4Group *parent() const { return d_parent;}
+    void set_parent(D4Group *g) { d_parent = g; }
+
+    /** Append a new dimension.
+     * In DAP4 dimensions are either of a known size or are varying. For
+     * fixed-size dimensions, the value of varying should be false. For varying
+     * dimensions the value of 'size' will be ignored - any value can be used
+     * when called this method.
+     *
+     * @param dim Pointer to the D4Dimension object to add; deep copy
+     */
+    void add_dim(D4Dimension *dim) { add_dim_nocopy(new D4Dimension(*dim)); }
+
+    /** Append a new dimension.
+     * @param dim Pointer to the D4Dimension object to add; copies the pointer
+     */
+    void add_dim_nocopy(D4Dimension *dim) { dim->set_parent(this); d_dims.push_back(dim); }
+
+    /// Get an iterator to the start of the dimensions
+    D4DimensionsIter dim_begin() { return d_dims.begin(); }
+
+    /// Get an iterator to the end of the dimensions
+    D4DimensionsIter dim_end() { return d_dims.end(); }
+
+    D4Dimension *find_dim(const string &name);
+
+    /** Insert a dimension.
+     * Insert a dimension before the position specified by the iterator.
+     * @note Calling this method invalidates all iterators that reference this
+     * D4Dimension object.
+     * @param dim Inserted before i; deep copy
+     * @param i iterator
+     */
+    void insert_dim(D4Dimension *dim, D4DimensionsIter i) {
+    	insert_dim_nocopy(new D4Dimension(*dim), i);
     }
 
-    string get_dim_name(int i) { return d_dims.at(i).name; }
-    unsigned long get_dim_size(int i) { return d_dims.at(i).size; }
+    /** Insert a dimension.
+     * @param dim Inserted before i; pointer copy
+     * @param i iterator
+     */
+    void insert_dim_nocopy(D4Dimension *dim, D4DimensionsIter i) {
+    	dim->set_parent(this);
+        d_dims.insert(i, dim);
+    }
 
-    D4DimensionsIter maps_begin() { return d_dims.begin(); }
-    D4DimensionsIter maps_end() { return d_dims.end(); }
-    string get_dim_name(D4DimensionsIter i) { return (*i).name; }
-    unsigned long get_dim_size(D4DimensionsIter i) { return (*i).size; }
+    void print_dap4(XMLWriter &xml, bool constrained = false) const;
 };
 
 } /* namespace libdap */
diff --git a/D4Enum.cc b/D4Enum.cc
new file mode 100644
index 0000000..efc476f
--- /dev/null
+++ b/D4Enum.cc
@@ -0,0 +1,412 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 <cassert>
+#include <sstream>
+
+#include "Byte.h"           // synonymous with UInt8 and Char
+#include "Int8.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+
+#include "D4Group.h"
+#include "D4Enum.h"
+#include "D4EnumDefs.h"
+#include "D4Attributes.h"
+
+#include "Float32.h"
+#include "Float64.h"
+
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
+#include "Operators.h"
+#include "InternalErr.h"
+#include "util.h"
+#include "debug.h"
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+// Explicit instantiation of the template member function 'value(T *)'.
+// This is required in order to have the library contain these member
+// function when its own code does not use them. Normally, C++ instantiates
+// templates when they are used, and this forces that process so the
+// library file contains the various versions of the member function.
+//
+// NB: I could not get this syntax to work in the header file. jhrg 8/19/13
+template void D4Enum::value<dods_byte>(dods_byte *v) const;
+template void D4Enum::value<dods_int16>(dods_int16 *v) const;
+template void D4Enum::value<dods_uint16>(dods_uint16 *v) const;
+template void D4Enum::value<dods_int32>(dods_int32 *v) const;
+template void D4Enum::value<dods_uint32>(dods_uint32 *v) const;
+template void D4Enum::value<dods_int64>(dods_int64 *v) const;
+template void D4Enum::value<dods_uint64>(dods_uint64 *v) const;
+
+template void D4Enum::set_value<dods_byte>(dods_byte v);
+template void D4Enum::set_value<dods_int16>(dods_int16 v);
+template void D4Enum::set_value<dods_uint16>(dods_uint16 v);
+template void D4Enum::set_value<dods_int32>(dods_int32 v);
+template void D4Enum::set_value<dods_uint32>(dods_uint32 v);
+template void D4Enum::set_value<dods_int64>(dods_int64 v);
+template void D4Enum::set_value<dods_uint64>(dods_uint64 v);
+
+void
+D4Enum::set_enumeration(D4EnumDef *enum_def) {
+    d_enum_def = enum_def;
+    d_element_type = enum_def->type();
+}
+
+void
+D4Enum::compute_checksum(Crc32 &checksum)
+{
+    switch (d_element_type) {
+    case dods_byte_c:
+    case dods_uint8_c:
+    case dods_int8_c:
+        checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf.ui8), sizeof(uint8_t));
+        break;
+    case dods_uint16_c:
+    case dods_int16_c:
+        checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf.ui16), sizeof(uint16_t));
+        break;
+    case dods_uint32_c:
+    case dods_int32_c:
+        checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf.ui32), sizeof(uint32_t));
+        break;
+    case dods_uint64_c:
+    case dods_int64_c:
+        checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf.ui64), sizeof(uint64_t));
+        break;
+
+    default:
+        assert(!"illegal type for D4Enum");
+    }
+}
+
+
+/**
+ * @brief Serialize a D4Enum
+ * Use the (integer) data type associated with an Enumeration definition to
+ * serialize the value of a D4Enum variable. This send just the bits that
+ * correspond to the declared type, not all 64-bits of storage used by a
+ * scalar D4Enum.
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+D4Enum::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+	switch (d_element_type) {
+	case dods_byte_c:
+	case dods_uint8_c:
+		m.put_byte(d_buf.ui8);
+		break;
+	case dods_uint16_c:
+		m.put_uint16(d_buf.ui16);
+		break;
+	case dods_uint32_c:
+		m.put_uint32(d_buf.ui32);
+		break;
+	case dods_uint64_c:
+		m.put_uint64(d_buf.ui64);
+		break;
+
+	case dods_int8_c:
+		m.put_int8(d_buf.i8);
+		break;
+	case dods_int16_c:
+		m.put_int16(d_buf.i16);
+		break;
+	case dods_int32_c:
+		m.put_int32(d_buf.i32);
+		break;
+	case dods_int64_c:
+		m.put_int64(d_buf.i64);
+		break;
+	default:
+		assert(!"illegal type for D4Enum");
+	}
+}
+
+void
+D4Enum::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+	switch (d_element_type) {
+	case dods_byte_c:
+	case dods_uint8_c:
+		um.get_byte(d_buf.ui8);
+		break;
+	case dods_uint16_c:
+		um.get_uint16(d_buf.ui16);
+		break;
+	case dods_uint32_c:
+		um.get_uint32(d_buf.ui32);
+		break;
+	case dods_uint64_c:
+		um.get_uint64(d_buf.ui64);
+		break;
+
+	case dods_int8_c:
+		um.get_int8(d_buf.i8);
+		break;
+	case dods_int16_c:
+		um.get_int16(d_buf.i16);
+		break;
+	case dods_int32_c:
+		um.get_int32(d_buf.i32);
+		break;
+	case dods_int64_c:
+		um.get_int64(d_buf.i64);
+		break;
+	default:
+		assert(!"illegal type for D4Enum");
+	}
+}
+
+unsigned int D4Enum::val2buf(void *val, bool)
+{
+    if (!val)
+        throw InternalErr("The incoming pointer does not contain any data.");
+
+    switch (d_element_type) {
+     case dods_byte_c:
+     case dods_uint8_c:
+         d_buf.ui8 = *(dods_byte*)val;
+         break;
+     case dods_uint16_c:
+         d_buf.ui16 = *(dods_uint16*)val;
+         break;
+     case dods_uint32_c:
+         d_buf.ui32 = *(dods_uint32*)val;
+         break;
+     case dods_uint64_c:
+         d_buf.ui64 = *(dods_uint64*)val;
+         break;
+
+     case dods_int8_c:
+         d_buf.i8 = *(dods_int8*)val;
+         break;
+     case dods_int16_c:
+         d_buf.i16 = *(dods_int16*)val;
+         break;
+     case dods_int32_c:
+         d_buf.i32 = *(dods_int32*)val;
+         break;
+     case dods_int64_c:
+         d_buf.i64 = *(dods_int64*)val;
+         break;
+     default:
+         assert(!"illegal type for D4Enum");
+     }
+
+    return width();
+}
+
+unsigned int D4Enum::buf2val(void **val)
+{
+    if (!val)
+        throw InternalErr("NULL pointer");
+
+    switch (d_element_type) {
+     case dods_byte_c:
+     case dods_uint8_c:
+         if (!*val) *val = new dods_byte;
+         *(dods_byte *) * val = d_buf.ui8;
+         break;
+     case dods_uint16_c:
+         if (!*val) *val = new dods_uint16;
+         *(dods_uint16 *) * val = d_buf.ui16;
+         break;
+     case dods_uint32_c:
+         if (!*val) *val = new dods_uint32;
+         *(dods_uint32 *) * val = d_buf.ui32;
+         break;
+     case dods_uint64_c:
+         if (!*val) *val = new dods_uint64;
+         *(dods_uint64 *) * val = d_buf.ui64;
+         break;
+
+     case dods_int8_c:
+         if (!*val) *val = new dods_int8;
+         *(dods_int8*) * val = d_buf.i8;
+         break;
+     case dods_int16_c:
+         if (!*val) *val = new dods_int16;
+         *(dods_int16 *) * val = d_buf.i16;
+         break;
+     case dods_int32_c:
+         if (!*val) *val = new dods_int32;
+         *(dods_int32 *) * val = d_buf.i32;
+         break;
+     case dods_int64_c:
+         if (!*val) *val = new dods_int64;
+         *(dods_int64 *) * val = d_buf.i64;
+         break;
+     default:
+         assert(!"illegal type for D4Enum");
+     }
+
+    return width();
+}
+
+void D4Enum::print_val(ostream &out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        out << " = ";
+    }
+
+    if (is_signed()) {
+    	int64_t v;
+    	value(&v);
+    	out << v;
+    }
+    else {
+    	uint64_t v;
+    	value(&v);
+    	out << v;
+    }
+
+    if (print_decl_p)
+    	out << ";" << endl;
+}
+
+/** 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
+D4Enum::print_xml_writer(XMLWriter &xml, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"Enum") < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write Enum element");
+
+    if (!name().empty())
+        if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
+            throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+
+
+    string path = d_enum_def->name();
+    // Not every D4EnumDef is a member of an instance of D4EnumDefs - the D4EnumDefs instance
+    // holds a reference to the D4Group that holds the Enum definitions.
+    // TODO Should this be changed - so the EnumDef holds a reference to its parent Group?
+    if (d_enum_def->parent()) {
+    	// print the FQN for the enum def; D4Group::FQN() includes the trailing '/'
+    	path = static_cast<D4Group*>(d_enum_def->parent()->parent())->FQN() + path;
+    }
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "enum", (const xmlChar*)path.c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for enum");
+
+    attributes()->print_dap4(xml);
+
+    if (get_attr_table().get_size() > 0)
+        get_attr_table().print_xml_writer(xml);
+
+    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not end Enum element");
+}
+
+
+bool
+D4Enum::ops(BaseType *b, int op)
+{
+    // Get the arg's value.
+    if (!read_p() && !read())
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+
+    // Get the second arg's value.
+    if (!b->read_p() && !b->read())
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+
+    switch (b->type()) {
+        case dods_int8_c:
+            return Cmp<dods_int64, dods_int8>(op, d_buf, static_cast<Int8*>(b)->value());
+        case dods_byte_c:
+            return SUCmp<dods_int64, dods_byte>(op, d_buf, static_cast<Byte*>(b)->value());
+        case dods_int16_c:
+            return Cmp<dods_int64, dods_int16>(op, d_buf, static_cast<Int16*>(b)->value());
+        case dods_uint16_c:
+            return SUCmp<dods_int64, dods_uint16>(op, d_buf, static_cast<UInt16*>(b)->value());
+        case dods_int32_c:
+            return Cmp<dods_int64, dods_int32>(op, d_buf, static_cast<Int32*>(b)->value());
+        case dods_uint32_c:
+            return SUCmp<dods_int64, dods_uint32>(op, d_buf, static_cast<UInt32*>(b)->value());
+#if 0
+            // FIXME
+        case dods_int64_c:
+            return Cmp<dods_int64, dods_int64>(op, d_buf, static_cast<D4Enum*>(b)->value());
+        case dods_uint64_c:
+            return SUCmp<dods_int64, dods_uint64>(op, d_buf, static_cast<D4Enum*>(b)->value());
+#endif
+        case dods_float32_c:
+            return Cmp<dods_int64, dods_float32>(op, d_buf, static_cast<Float32*>(b)->value());
+        case dods_float64_c:
+            return Cmp<dods_int64, dods_float64>(op, d_buf, static_cast<Float64*>(b)->value());
+        default:
+            return false;
+    }
+
+    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
+D4Enum::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "D4Enum::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "value: " << d_buf.ui64 << endl ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/D4Enum.h b/D4Enum.h
new file mode 100644
index 0000000..a09b214
--- /dev/null
+++ b/D4Enum.h
@@ -0,0 +1,281 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 _D4Enum_h
+#define _D4Enum_h 1
+
+#include <cassert>
+
+#include "BaseType.h"
+
+#include "InternalErr.h"
+#include "dods-datatypes.h"
+#include "util.h"
+
+namespace libdap
+{
+
+class D4EnumDef;
+class ConstraintEvaluator;
+class Marshaller;
+class UnMarshaller;
+
+/**
+ * @brief Holds a DAP4 enumeration.
+ *
+ * @note When constructed a type for the Enum must be specified. If
+ * it is not an integer type, the Enum will use unsigned int 64. This
+ * is not the same as the enumeration type that is defined using the
+ * Enumeration XML element in the DMR - that information is stored
+ * in additional fields and used for checking values and printing the
+ * variable's declaration, but not for the internal storage of values.
+ */
+class D4Enum: public BaseType
+{
+	friend class D4EnumTest;
+
+public:
+    union enum_value {
+    	int8_t i8;
+    	uint8_t ui8;
+    	int16_t i16;
+    	uint16_t ui16;
+    	int32_t i32;
+    	uint32_t ui32;
+    	int64_t i64;
+    	uint64_t ui64;
+
+    	enum_value() : ui64(0) { }
+
+    	enum_value(int8_t i) : i8(i) {}
+    	enum_value(uint8_t i) : ui8(i) {}
+    	enum_value(int16_t i) : i16(i) {}
+    	enum_value(uint16_t i) : ui16(i) {}
+    	enum_value(int32_t i) : i32(i) {}
+    	enum_value(uint32_t i) : ui32(i) {}
+    	enum_value(int64_t i) : i64(i) {}
+    	enum_value(uint64_t i) : ui64(i) {}
+
+    	// cast operators; use by set_value()
+    	operator int8_t() const { return i8; }
+    	operator uint8_t() const { return ui8; }
+    	operator int16_t() const { return i16; }
+    	operator uint16_t() const { return ui16; }
+    	operator int32_t() const { return i32; }
+    	operator uint32_t() const { return ui32; }
+    	operator int64_t() const { return i64; }
+    	operator uint64_t() const { return ui64; }
+    };
+
+private:
+    enum_value d_buf;
+
+    Type d_element_type;
+    D4EnumDef *d_enum_def;	// The enumeration defined in the DMR, not an integer type
+    bool d_is_signed;
+
+    void m_duplicate(const D4Enum &src) {
+        d_buf = src.d_buf;
+        d_element_type = src.d_element_type;
+    }
+
+    unsigned int m_type_width() const {
+        switch(d_element_type) {
+            case dods_byte_c:
+            case dods_int8_c:
+            case dods_uint8_c:
+                return 1;
+            case dods_int16_c:
+            case dods_uint16_c:
+                return 2;
+            case dods_int32_c:
+            case dods_uint32_c:
+                return 4;
+            case dods_int64_c:
+            case dods_uint64_c:
+                return 8;
+            case dods_null_c:
+            default:
+            	assert(!"illegal type for D4Enum");
+            	return 0;
+        }
+    }
+
+	D4Enum();	// No empty constructor
+
+public:
+	// TODO add a way to set the EnumDef to these
+    D4Enum(const string &name, const string &enum_type) : BaseType(name, dods_enum_c, true /*is_dap4*/),
+			d_buf((uint64_t)0), d_element_type(dods_null_c) {
+    	d_element_type = get_type(enum_type.c_str());
+    	// assert(is_integer_type(d_element_type));
+    	if (!is_integer_type(d_element_type)) d_element_type = dods_uint64_c;
+    	set_is_signed(d_element_type);
+    }
+
+    D4Enum(const string &name, Type type) : BaseType(name, dods_enum_c, true /*is_dap4*/),
+    		d_buf((uint64_t)0), d_element_type(type) {
+    	//assert(is_integer_type(d_element_type));
+    	if (!is_integer_type(d_element_type)) d_element_type = dods_uint64_c;
+    	set_is_signed(d_element_type);
+    }
+
+    D4Enum(const string &name, const string &dataset, Type type) : BaseType(name, dataset, dods_enum_c, true /*is_dap4*/),
+    		d_buf((uint64_t)0), d_element_type(type) {
+    	//assert(is_integer_type(d_element_type));
+    	if (!is_integer_type(d_element_type)) d_element_type = dods_uint64_c;
+    	set_is_signed(d_element_type);
+    }
+
+    D4Enum(const D4Enum &src) : BaseType(src) { m_duplicate(src); }
+
+    D4Enum &operator=(const D4Enum &rhs) {
+        if (this == &rhs)
+            return *this;
+        static_cast<BaseType &>(*this) = rhs;
+        m_duplicate(rhs);
+        return *this;
+    }
+
+    virtual ~D4Enum() { }
+
+    virtual D4EnumDef *enumeration() const { return d_enum_def; }
+    virtual void set_enumeration(D4EnumDef *enum_def);
+
+    virtual BaseType *ptr_duplicate() { return new D4Enum(*this); }
+
+    Type element_type() { return d_element_type; }
+    void set_element_type(Type type) { d_element_type = type; }
+
+    bool is_signed() const { return d_is_signed; }
+    void set_is_signed(Type t) {
+    	switch (t) {
+    	case dods_byte_c:
+    	case dods_uint8_c:
+    	case dods_uint16_c:
+    	case dods_uint32_c:
+    	case dods_uint64_c:
+    		d_is_signed = false;
+    		break;
+
+    	case dods_int8_c:
+    	case dods_int16_c:
+    	case dods_int32_c:
+    	case dods_int64_c:
+    		d_is_signed =  true;
+    		break;
+
+    	default:
+    		assert(!"illegal type for D4Enum");
+    		throw InternalErr(__FILE__, __LINE__, "Illegal type");
+    	}
+    }
+
+    /**
+     * @brief Copy the value of this Enum into \c v.
+     * Template member function that can be used to read the value of the
+     * Enum. This template is explicitly instantiated so libdap includes
+     * D4Enum::value(dods_byte* v), ..., value(dods_uint64) (i.e., all
+     * of the integer types).
+     *
+     * @param v Value-result parameter; return the value of the Enum
+     * in this variable.
+     */
+	template<typename T> void value(T *v) const
+	{
+		switch (d_element_type) {
+		case dods_byte_c:
+		case dods_uint8_c:
+			*v = static_cast<T>(d_buf.ui8);
+			break;
+		case dods_uint16_c:
+			*v = static_cast<T>(d_buf.ui16);
+			break;
+		case dods_uint32_c:
+			*v = static_cast<T>(d_buf.ui32);
+			break;
+		case dods_uint64_c:
+			*v = static_cast<T>(d_buf.ui64);
+			break;
+
+		case dods_int8_c:
+			*v = static_cast<T>(d_buf.i8);
+			break;
+		case dods_int16_c:
+			*v = static_cast<T>(d_buf.i16);
+			break;
+		case dods_int32_c:
+			*v = static_cast<T>(d_buf.i32);
+			break;
+		case dods_int64_c:
+			*v = static_cast<T>(d_buf.i64);
+			break;
+		default:
+			assert(!"illegal type for D4Enum");
+		}
+	}
+
+    /**
+     * @brief Set the value of the Enum
+     * Template member function to set the value of the Enum. The libdap library
+     * contains versions of this member function for dods_byte, ..., dods_uint64
+     * types for the parameter \c v.
+     *
+     * @param v Set the Enum to this value.
+     */
+    template <typename T> void set_value(T v) { d_buf = v; }
+
+    /**
+     * @brief Return the number of bytes in an instance of an Enum.
+     * This returns the number of bytes an instance of Enum will use
+     * either in memory or on the wire (i.e., in a serialization of
+     * the type).
+     *
+     * @note This version of the method works for scalar Enums only.
+     * @return The number of bytes used by a value.
+     */
+    virtual unsigned int width(bool /* constrained */ = false) const { return m_type_width(); }
+
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
+    virtual void print_val(ostream &out, string space = "", bool print_decl_p = true);
+
+    virtual void print_xml_writer(XMLWriter &xml, bool constrained);
+
+    virtual bool ops(BaseType *b, int op);
+
+    virtual void dump(ostream &strm) const;
+
+    unsigned int val2buf(void *, bool);
+    unsigned int buf2val(void **);
+};
+
+} // namespace libdap
+
+#endif // _D4Enum_h
+
diff --git a/D4EnumDef.cc b/D4EnumDef.cc
deleted file mode 100644
index 216af82..0000000
--- a/D4EnumDef.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * D4EnumDef.cc
- *
- *  Created on: Oct 9, 2012
- *      Author: jimg
- */
-
-#include "D4EnumDef.h"
-
-#include <sstream>
-
-#include "util.h"
-
-namespace libdap {
-
-#if 0
-string D4EnumDef::type_name() {
-    switch (d_type) {
-    case dods_int8_c:
-        return string("Int8");
-    case dods_uint8_c:
-        return string("UInt8");
-    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_int64_c:
-        return string("Int64");
-    case dods_uint64_c:
-        return string("UInt64");
-
-    default:
-        throw InternalErr(__FILE__, __LINE__, "Invalid enumeration basetype.");
-    }
-}
-#endif
-
-void D4EnumDef::print_enum_const(XMLWriter *xml, const enum_val ev)
-{
-    if (xmlTextWriterStartElement(xml->get_writer(), (const xmlChar*)"EnumConst") < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not write EnumConst element");
-
-    if (xmlTextWriterWriteAttribute(xml->get_writer(), (const xmlChar*) "name", (const xmlChar*)ev.d_item.c_str()) < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
-
-    ostringstream oss;
-    oss << ev.d_val;
-    if (xmlTextWriterWriteAttribute(xml->get_writer(), (const xmlChar*) "value", (const xmlChar*)oss.str().c_str()) < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for value");
-
-    if (xmlTextWriterEndElement(xml->get_writer()) < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not end EnumConst element");
-
-}
-
-void D4EnumDef::print_xml_writer(XMLWriter &xml)
-{
-    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"Enumeration") < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not write Enumeration element");
-
-    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
-
-    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "basetype", (const xmlChar*)type_name(d_type).c_str()) < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
-
-    for_each(d_values.begin(), d_values.end(), bind1st(ptr_fun(print_enum_const), &xml));
-
-    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not end Enumeration element");
-}
-
-} /* namespace libdap */
diff --git a/D4EnumDef.h b/D4EnumDef.h
deleted file mode 100644
index fd04eb5..0000000
--- a/D4EnumDef.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * D4EnumDef.h
- *
- *  Created on: Oct 9, 2012
- *      Author: jimg
- */
-
-#ifndef D4ENUMDEF_H_
-#define D4ENUMDEF_H_
-
-#include <string>
-#include <vector>
-#include <algorithm>
-#include <functional>
-
-#include "BaseType.h"
-
-using namespace std;
-
-namespace libdap {
-
-class D4EnumDef {
-    string d_name; /// The name of the enum definition
-    Type d_type; /// Enums are always integer types
-
-    struct enum_val {
-        string d_item;
-        // cast to unsigned based on d_type.
-        long long d_val;
-
-        enum_val(const string &item, unsigned long val) :
-                d_item(item), d_val(val)
-        {
-        }
-    };
-
-    vector<enum_val> d_values;
-    typedef vector<enum_val>::iterator enumValIter;
-
-public:
-    D4EnumDef() {}
-    D4EnumDef(const string &name, Type type) : d_name(name), d_type(type) {}
-
-    virtual ~D4EnumDef() {}
-
-    string get_name() const { return d_name; }
-    void set_name(const string &name) { d_name = name; }
-
-    Type get_type() const { return d_type; }
-    void set_type(Type t) { d_type = t; }
-
-    void add_value(const string &item, unsigned long val) {
-        d_values.push_back(enum_val(item, val));
-    }
-
-    enumValIter begin_vals() { return d_values.begin(); }
-    enumValIter end_vals() { return d_values.end(); }
-    long long get_value(enumValIter i) { return i->d_val; }
-    string get_item(enumValIter i ) { return i->d_item; }
-
-    static bool is_item(const enum_val e, const string item) {
-        return e.d_item == item;
-    }
-
-    // Written to use for_each() as an exercise... Cannot use reference
-    // types in is_item(...)
-    long long get_value(const string &item) {
-        // lookup name and return d_val;
-        enumValIter i = find_if(d_values.begin(), d_values.end(),
-                bind2nd(ptr_fun(libdap::D4EnumDef::is_item), item));
-        return i->d_val;
-    }
-
-private:
-#if 0
-    string type_name();
-#endif
-    static void print_enum_const(XMLWriter *xml, const enum_val ev);
-
-public:
-    void print_xml_writer(XMLWriter &xml);
-};
-
-} /* namespace libdap */
-#endif /* D4ENUMDEF_H_ */
diff --git a/D4EnumDefs.cc b/D4EnumDefs.cc
new file mode 100644
index 0000000..737623f
--- /dev/null
+++ b/D4EnumDefs.cc
@@ -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) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include "D4Group.h"
+#include "D4EnumDefs.h"
+
+#include <sstream>
+
+#include "dods-limits.h"
+#include "util.h"
+
+namespace libdap {
+
+/** Test if a particular value is legal for a given type. In a D4EnumDef,
+ * all values are actually stored in a long long, but the different
+ * enumerations can specify different types like Byte, Int32, ..., and this
+ * method is used to test that the values match those types.
+ */
+bool
+D4EnumDef::is_valid_enum_value(long long value)
+{
+    switch (type()) {
+        case dods_int8_c:
+            return (value >= DODS_SCHAR_MIN && value <= DODS_SCHAR_MAX);
+        case dods_byte_c:
+        case dods_uint8_c:
+            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UCHAR_MAX);
+        case dods_int16_c:
+            return (value >= DODS_SHRT_MIN && value <= DODS_SHRT_MAX);
+        case dods_uint16_c:
+            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_USHRT_MAX);
+        case dods_int32_c:
+            return (value >= DODS_INT_MIN && value <= DODS_INT_MAX);
+        case dods_uint32_c:
+            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UINT_MAX);
+        case dods_int64_c:
+            return (value >= DODS_LLONG_MIN && value <= DODS_LLONG_MAX);
+        case dods_uint64_c:
+            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_ULLONG_MAX);
+        default:
+            return false;
+    }
+}
+
+// Note that in order for this to work the second argument must not be a reference.
+// jhrg 8/20/13
+static bool
+enum_def_name_eq(D4EnumDef *d, const string name)
+{
+    return d->name() == name;
+}
+
+D4EnumDef *
+D4EnumDefs::find_enum_def(const string &name)
+{
+    D4EnumDefIter d = find_if(d_enums.begin(), d_enums.end(), bind2nd(ptr_fun(enum_def_name_eq), name));
+    return (d != d_enums.end()) ? *d: 0;
+}
+
+void D4EnumDef::print_value(XMLWriter &xml, const D4EnumDef::tuple &tuple) const
+{
+    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"EnumConst") < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write EnumConst element");
+
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)tuple.label.c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+
+    ostringstream oss;
+    oss << tuple.value;
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "value", (const xmlChar*)oss.str().c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for value");
+
+    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not end EnumConst element");
+}
+
+void D4EnumDef::print_dap4(XMLWriter &xml) const
+{
+    vector<D4EnumDef::tuple>::const_iterator i = d_tuples.begin();
+    while(i != d_tuples.end()) {
+        print_value(xml, *i++);
+    }
+}
+
+void D4EnumDefs::m_print_enum(XMLWriter &xml, D4EnumDef *e) const
+{
+    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"Enumeration") < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write Enumeration element");
+
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)e->name().c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "basetype", (const xmlChar*)D4type_name(e->type()).c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+
+    // print each of e.values
+    e->print_dap4(xml);
+
+    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not end Enumeration element");
+}
+
+void D4EnumDefs::print_dap4(XMLWriter &xml, bool constrained) const
+{
+    D4EnumDefCIter i = d_enums.begin();
+    while (i != d_enums.end()) {
+        if (!constrained || parent()->find_first_var_that_uses_enumeration(*i))
+            m_print_enum(xml, *i);
+        ++i;
+    }
+}
+
+} /* namespace libdap */
diff --git a/D4EnumDefs.h b/D4EnumDefs.h
new file mode 100644
index 0000000..e5a7c5b
--- /dev/null
+++ b/D4EnumDefs.h
@@ -0,0 +1,170 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef D4ENUMDEF_H_
+#define D4ENUMDEF_H_
+
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <functional>
+
+#include "BaseType.h"
+
+using namespace std;
+
+namespace libdap {
+
+class D4EnumDefs;
+class D4Group;
+
+class D4EnumDef {
+    string d_name;
+    Type d_type;
+    D4EnumDefs *d_parent;
+
+    struct tuple {
+        string label;
+        long long value;
+
+        tuple(const string &l, long long v) : label(l), value(v) {}
+    };
+
+    vector<tuple> d_tuples;
+
+    void print_value(XMLWriter &xml, const D4EnumDef::tuple &tuple) const;
+
+public:
+    typedef vector<tuple>::iterator D4EnumValueIter;
+
+    D4EnumDef() : d_name(""), d_type(dods_null_c), d_parent(0) {}
+    D4EnumDef(const string &n, const Type &t, D4EnumDefs *e = 0) : d_name(n), d_type(t), d_parent(e) {}
+
+    string name() const { return d_name; }
+    void set_name(const string &n) { d_name = n; }
+
+    Type type() const { return d_type; }
+    void set_type(Type t) { d_type = t; }
+
+    D4EnumDefs *parent() const { return d_parent; }
+    void set_parent(D4EnumDefs *e) { d_parent = e; }
+
+    bool empty() const { return d_tuples.empty(); }
+
+    void add_value(const string &label, long long value) {
+        d_tuples.push_back(tuple(label, value));
+    }
+
+    D4EnumValueIter value_begin() { return d_tuples.begin(); }
+    D4EnumValueIter value_end() { return d_tuples.end(); }
+    string &label(D4EnumValueIter i) { return (*i).label; }
+    long long value(D4EnumValueIter i) { return (*i).value; }
+
+    bool is_valid_enum_value(long long value);
+    void print_dap4(XMLWriter &xml) const;
+};
+
+/** The Enumerations defined for a Group. */
+class D4EnumDefs {
+    vector<D4EnumDef*> d_enums;
+
+    D4Group *d_parent;		// the group that holds this set of D4EnumDefs; weak pointer, don't delete
+
+    void m_print_enum(XMLWriter &xml, D4EnumDef *e) const;
+
+    void m_duplicate(const D4EnumDefs &rhs) {
+        D4EnumDefCIter i = rhs.d_enums.begin();
+        while (i != rhs.d_enums.end()) {
+            d_enums.push_back(new D4EnumDef(**i++));    // deep copy
+        }
+
+        d_parent = rhs.d_parent;
+    }
+
+public:
+    typedef vector<D4EnumDef*>::iterator D4EnumDefIter;
+    typedef vector<D4EnumDef*>::const_iterator D4EnumDefCIter;
+
+    D4EnumDefs() : d_parent(0) {}
+    D4EnumDefs(const D4EnumDefs &rhs) {
+        m_duplicate(rhs);
+    }
+
+    virtual ~D4EnumDefs() {
+        D4EnumDefIter i = d_enums.begin();
+        while(i != d_enums.end()) {
+            delete *i++;
+        }
+    }
+
+    D4EnumDefs &operator=(const D4EnumDefs &rhs) {
+        if (this == &rhs) return *this;
+        m_duplicate(rhs);
+        return *this;
+    }
+
+    bool empty() const { return d_enums.empty(); }
+
+    D4Group *parent() const { return d_parent; }
+    void set_parent(D4Group *p) { d_parent = p; }
+
+    /** Append a new D4EnumDef.
+     *
+     * @param enum_def The enumeration.
+     */
+    void add_enum(D4EnumDef *enum_def) {
+    	add_enum_nocopy(new D4EnumDef(*enum_def));
+    }
+    void add_enum_nocopy(D4EnumDef *enum_def) {
+    	enum_def->set_parent(this);
+        d_enums.push_back(enum_def);
+    }
+
+    /// Get an iterator to the start of the enumerations
+    D4EnumDefIter enum_begin() { return d_enums.begin(); }
+
+    /// Get an iterator to the end of the enumerations
+    D4EnumDefIter enum_end() { return d_enums.end(); }
+
+    D4EnumDef *find_enum_def(const string &name);
+
+    /**
+     * @brief Insert a D4EnumDef.
+     * Insert a D4EnumDef before the position specified by the iterator.
+     * @note Calling this method invalidates all iterators that reference this
+     * D4EnumDef object.
+     * @param enum_def Make a deep copy and insert the enumeration definition
+     * @param i iterator
+     */
+    void insert_enum(D4EnumDef *enum_def, D4EnumDefIter i) {
+    	D4EnumDef *enum_def_copy = new D4EnumDef(*enum_def);
+    	enum_def_copy->set_parent(this);
+        d_enums.insert(i, enum_def_copy);
+    }
+
+    void print_dap4(XMLWriter &xml, bool constrained = false) const;
+};
+
+} /* namespace libdap */
+#endif /* D4ENUMDEF_H_ */
diff --git a/D4ParseError.h b/D4Function.h
similarity index 61%
rename from D4ParseError.h
rename to D4Function.h
index ede678f..172b0fe 100644
--- a/D4ParseError.h
+++ b/D4Function.h
@@ -1,10 +1,9 @@
-
 // -*- mode: c++; c-basic-offset:4 -*-
 
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
 // Access Protocol.
 
-// Copyright (c) 2012 OPeNDAP, Inc.
+// Copyright (c) 2014 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -23,27 +22,25 @@
 //
 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
-#ifndef d4_parse_error_h
-#define d4_parse_error_h
 
-#ifndef _error_h
-#include "Error.h"
-#endif
+#ifndef D_FUNCTION_H_
+#define D_FUNCTION_H_
+
+namespace libdap {
 
-namespace libdap
-{
+class BaseType;
+class D4RValueList;
+class DMR;
+
+// D4Function is a pointer to a function that takes a pointer to an RValueList and
+// a reference to a DMR and returns a pointer to a BaseTYpe.
+//
+// I think this would be better as a 'function that takes...' instead of a 'pointer
+// to a function that takes...' but I used this to make the code fit more closely to
+// the pattern established by the DAP2 CE functions. jhrg 3/10/14
 
-/** Thrown when the DDX response cannot be parsed.. */
-class D4ParseError : public Error
-{
-public:
-    D4ParseError() : Error("The DDX response document parse failed.")
-    {}
-    D4ParseError(const string &msg) :
-            Error(string("The DDX response document parse failed: ") + msg)
-    {}
-};
+typedef BaseType* (*D4Function)(D4RValueList *, DMR &);
 
-} // namespace libdap
+}// namespace libdap
 
-#endif // d4_parse_error_h
+#endif /* D_FUNCTION_H_ */
diff --git a/D4Group.cc b/D4Group.cc
index d96eb93..29b8b22 100644
--- a/D4Group.cc
+++ b/D4Group.cc
@@ -1,23 +1,99 @@
-/*
- * D4Group.cc
- *
- *  Created on: Sep 27, 2012
- *      Author: jimg
- */
+// -*- mode: c++; c-basic-offset:4 -*-
 
-#include "D4Group.h"
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+#include <stdint.h>
+
+//#define DODS_DEBUG
+
+#include "crc.h"
 
 #include "BaseType.h"
+#include "Array.h"
+
+#include "XMLWriter.h"
+#include "D4Attributes.h"
+#include "D4Dimensions.h"
+#include "D4Group.h"
+#include "D4Enum.h"
+
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
+#include "debug.h"
 
 namespace libdap {
 
+void D4Group::m_duplicate(const D4Group &g)
+{
+	DBG(cerr << "In D4Group::m_duplicate for " << g.name() << endl);
+
+	// dims; deep copy, this is the parent
+	if (g.d_dims) {
+		d_dims = new D4Dimensions(*(g.d_dims));
+		d_dims->set_parent(this);
+	}
+
+	// Update all of the D4Dimension weak pointers in the Array objects.
+	// This is a hack - we know that Constructor::m_duplicate() has been
+	// called at this point and any Array instances have dimension pointers
+	// that reference the 'old' dimensions (g.d_dims) and not the 'new'
+	// dimensions made above. Scan every array and re-wire the weak pointers.
+	// jhrg 8/15/14
+	Vars_citer vi = d_vars.begin();
+	while (vi != d_vars.end()) {
+		if ((*vi)->type() == dods_array_c)
+			static_cast<Array*>(*vi)->update_dimension_pointers(g.d_dims, d_dims);
+		++vi;
+	}
+
+	// enums; deep copy
+	if (g.d_enum_defs) d_enum_defs = new D4EnumDefs(*g.d_enum_defs);
+
+    // groups
+    groupsCIter i = g.d_groups.begin();
+    while(i != g.d_groups.end()) {
+        D4Group *g = (*i++)->ptr_duplicate();
+        add_group_nocopy(g);
+    }
+
+    DBG(cerr << "Exiting D4Group::m_duplicate" << endl);
+}
+
 /** The D4Group 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.
 */
-D4Group::D4Group(const string &n) : Constructor(n, dods_group_c, /*is_dap4*/true)
+D4Group::D4Group(const string &name)
+    : Constructor(name, dods_group_c, /*is_dap4*/true), d_dims(0), d_enum_defs(0)
 {}
 
 /** The D4Group server-side constructor requires the name of the variable
@@ -27,27 +103,28 @@ D4Group::D4Group(const string &n) : Constructor(n, dods_group_c, /*is_dap4*/true
     @param n A string containing the name of the variable.
     @param d A string containing the name of the dataset.
 */
-D4Group::D4Group(const string &n, const string &d)
-    : Constructor(n, d, dods_group_c, /*is_dap4*/true)
+D4Group::D4Group(const string &name, const string &dataset)
+    : Constructor(name, dataset, dods_group_c, /*is_dap4*/true), d_dims(0), d_enum_defs(0)
 {}
 
 /** The D4Group copy constructor. */
-D4Group::D4Group(const D4Group &rhs) : Constructor(rhs)
+D4Group::D4Group(const D4Group &rhs) : Constructor(rhs), d_dims(0), d_enum_defs(0)
 {
+	DBG(cerr << "In D4Group::copy_ctor for " << rhs.name() << endl);
     m_duplicate(rhs);
 }
 
-static void enum_del(D4EnumDef *ed)
-{
-    delete ed;
-}
-
 D4Group::~D4Group()
 {
-    for_each(d_enums.begin(), d_enums.end(), enum_del);
+    delete d_dims;
+    delete d_enum_defs;
+
+    groupsIter i = d_groups.begin();
+    while(i != d_groups.end())
+        delete *i++;
 }
 
-BaseType *
+D4Group *
 D4Group::ptr_duplicate()
 {
     return new D4Group(*this);
@@ -66,65 +143,425 @@ D4Group::operator=(const D4Group &rhs)
     return *this;
 }
 
-void
-D4Group::add_enumeration_nocopy(D4EnumDef *enum_def)
+/**
+ * Get the Fully Qualified Name for this Group, including the Group. This
+ * uses the name representation described in the DAP4 specification.
+ *
+ * @return The FQN in a string
+ */
+string
+D4Group::FQN() const
 {
-    d_enums.push_back(enum_def);
+	// The root group is named "/" (always)
+	return (name() == "/") ? "/" : static_cast<D4Group*>(get_parent())->FQN() + name() + "/";
 }
 
-class PrintVariable : public unary_function<BaseType *, void>
+// Note that in order for this to work the second argument must not be a reference.
+// jhrg 8/20/13
+static bool
+name_eq(D4Group *g, const string name)
 {
-    XMLWriter &d_xml;
-    bool d_constrained;
-public:
-    PrintVariable(XMLWriter &x, bool c) : d_xml(x), d_constrained(c) {}
+	return g->name() == name;
+}
+
+D4Group *
+D4Group::find_child_grp(const string &grp_name)
+{
+	groupsIter g = find_if(grp_begin(), grp_end(), bind2nd(ptr_fun(name_eq), grp_name));
+	return (g == grp_end()) ? 0: *g;
+}
 
-    void operator()(BaseType *btp)
-    {
-        btp->print_xml_writer(d_xml, d_constrained);
+// TODO Add constraint param? jhrg 11/17/13
+BaseType *
+D4Group::find_first_var_that_uses_dimension(D4Dimension *dim)
+{
+    // for each group, starting with the root group
+    //    for each variable in the group that is marked to send and is an array
+    //        return the btp if it uses the D4Dimension
+    //    if it contains child groups, search those
+    //        return the btp if it uses the D4Dimension
+    // return null
+
+    // exhaustive breadth-first search for 'dim
+
+    // root group
+    for (Vars_iter i = var_begin(), e = var_end(); i != e; ++i) {
+        if ((*i)->send_p() && (*i)->type() == dods_array_c) {
+            Array *a = static_cast<Array*>(*i);
+            for (Array::Dim_iter di = a->dim_begin(), de = a->dim_end(); di != de; ++di) {
+                if (a->dimension_D4dim(di) == dim)
+                    return a;
+            }
+        }
     }
-};
 
-class PrintEnum : public unary_function<D4EnumDef *, void>
+    for (groupsIter i = grp_begin(), e = grp_end(); i != e; ++i) {
+        BaseType *btp = (*i)->find_first_var_that_uses_dimension(dim);
+        if (btp) return btp;
+    }
+
+    return 0;
+}
+
+BaseType *
+D4Group::find_first_var_that_uses_enumeration(D4EnumDef *enum_def)
 {
-    XMLWriter &d_xml;
+    // for each group, starting with the root group
+    //    for each variable in the group that is marked to send and is an array
+    //        return the btp if it uses the D4EnumDef
+    //    if it contains child groups, search those
+    //        return the btp if it uses the D4EnumDef
+    // return null
 
-public:
-    PrintEnum(XMLWriter &x) : d_xml(x){}
+    // exhaustive breadth-first search for 'dim
 
-    void operator()(D4EnumDef *e)
-    {
-        e->print_xml_writer(d_xml);
+    // root group
+    for (Vars_iter i = var_begin(), e = var_end(); i != e; ++i) {
+        if ((*i)->send_p() && (*i)->type() == dods_enum_c) {
+            D4Enum *e = static_cast<D4Enum*>(*i);
+            if (e->enumeration() == enum_def)
+                return e;
+        }
     }
-};
+
+    for (groupsIter i = grp_begin(), e = grp_end(); i != e; ++i) {
+        BaseType *btp = (*i)->find_first_var_that_uses_enumeration(enum_def);
+        if (btp) return btp;
+    }
+
+    return 0;
+}
+
+/**
+ * @brief Find the dimension using a path.
+ * Using the DAP4 name syntax, lookup a dimension. The dimension must
+ * be defined before it is used. The \c path argument may be either an
+ * absolute path or a relative path. Note that the name syntax does not
+ * provide for paths to contain an 'up one level' symbol.
+ * @param path The path to the dimension
+ * @return A pointer to the D4Dimension object.
+ */
+D4Dimension *
+D4Group::find_dim(const string &path)
+{
+	string lpath = path;		// get a mutable copy
+
+	// special-case for the root group
+	if (lpath[0] == '/') {
+		if (name() != "/")
+			throw InternalErr(__FILE__, __LINE__, "Lookup of a FQN starting in non-root group.");
+		else
+			lpath = lpath.substr(1);
+	}
+
+	string::size_type pos = lpath.find('/');
+	if (pos == string::npos) {
+		// name looks like 'bar'
+		return dims()->find_dim(lpath);
+	}
+
+	// name looks like foo/bar/baz where foo and bar must be groups
+	string grp_name = lpath.substr(0, pos);
+	lpath = lpath.substr(pos + 1);
+
+	D4Group *grp = find_child_grp(grp_name);
+	return (grp == 0) ? 0: grp->find_dim(lpath);
+}
+
+Array *
+D4Group::find_map_source(const string &path)
+{
+	BaseType *map_source = m_find_map_source_helper(path);
+
+	// TODO more complete semantic checking jhrg 10/16/13
+	if (map_source && map_source->type() == dods_array_c) return static_cast<Array*>(map_source);
+
+	return 0;
+}
+
+BaseType *
+D4Group::m_find_map_source_helper(const string &path)
+{
+	string lpath = path;		// get a mutable copy
+
+	// special-case for the root group
+	if (lpath[0] == '/') {
+		if (name() != "/")
+			throw InternalErr(__FILE__, __LINE__, "Lookup of a FQN starting in non-root group.");
+		else
+			lpath = lpath.substr(1);
+	}
+
+	string::size_type pos = lpath.find('/');
+	if (pos == string::npos) {
+		// name looks like 'bar'
+		return var(lpath);
+	}
+
+	// name looks like foo/bar/baz where foo an bar must be groups
+	string grp_name = lpath.substr(0, pos);
+	lpath = lpath.substr(pos + 1);
+
+	D4Group *grp = find_child_grp(grp_name);
+	return (grp == 0) ? 0: grp->var(lpath);
+}
+
+D4EnumDef *
+D4Group::find_enum_def(const string &path)
+{
+    string lpath = path;        // get a mutable copy
+
+    // special-case for the root group
+    if (lpath[0] == '/') {
+        if (name() != "/")
+            throw InternalErr(__FILE__, __LINE__, "Lookup of a FQN starting in non-root group.");
+        else
+            lpath = lpath.substr(1);
+    }
+
+    string::size_type pos = lpath.find('/');
+    if (pos == string::npos) {
+        // name looks like 'bar'
+        return enum_defs()->find_enum_def(lpath);
+    }
+
+    // name looks like foo/bar/baz where foo and bar must be groups
+    string grp_name = lpath.substr(0, pos);
+    lpath = lpath.substr(pos + 1);
+
+    D4Group *grp = find_child_grp(grp_name);
+    return (grp == 0) ? 0: grp->enum_defs()->find_enum_def(lpath);
+}
+
+/**
+ * Find a variable using it's FUlly Qualified Name (FQN). The leading '/' is optional.
+ *
+ * @param path The FQN to the variable
+ * @return A BaseType* to the variable of null if it was not found
+ * @see BaseType::FQN()
+ */
+BaseType *
+D4Group::find_var(const string &path)
+{
+    string lpath = path;        // get a mutable copy
+
+    // special-case for the root group
+    if (lpath[0] == '/') {
+        if (name() != "/")
+            throw InternalErr(__FILE__, __LINE__, "Lookup of a FQN starting in non-root group.");
+        else
+            lpath = lpath.substr(1);
+    }
+
+    string::size_type pos = lpath.find('/');
+    if (pos == string::npos) {
+        // name looks like 'bar' or bar.baz; lookup in the Constructor that's part of the Group
+    	return var(lpath);
+    }
+
+    // name looks like foo/bar/baz where foo and bar must be groups
+    string grp_name = lpath.substr(0, pos);
+    lpath = lpath.substr(pos + 1);
+
+    D4Group *grp = find_child_grp(grp_name);
+    return (grp == 0) ? 0 : grp->find_var(lpath);
+}
+
+/** Compute the size of all of the variables in this group and it's children,
+ * in kilobytes
+ *
+ * @param constrained Should the current constraint be taken into account?
+ * @return The size in kilobytes
+ */
+long
+D4Group::request_size(bool constrained)
+{
+    long long size = 0;
+    // variables
+    Constructor::Vars_iter v = var_begin();
+    while (v != var_end()) {
+        if (constrained) {
+            if ((*v)->send_p())
+                size += (*v)->width(constrained);
+        }
+        else {
+            size += (*v)->width(constrained);
+        }
+
+        ++v;
+    }
+
+    // groups
+    groupsIter g = d_groups.begin();
+    while (g != d_groups.end())
+        size += (*g++)->request_size(constrained);
+
+    return size / 1024;
+}
+
+void
+D4Group::set_read_p(bool state)
+{
+    groupsIter g = d_groups.begin();
+    while (g != d_groups.end())
+        (*g++)->set_read_p(state);
+
+    Constructor::set_read_p(state);
+}
 
 void
-D4Group::print_xml_writer(XMLWriter &xml, bool constrained)
+D4Group::set_send_p(bool state)
 {
-    if (constrained && !send_p())
-        return;
+    groupsIter g = d_groups.begin();
+    while (g != d_groups.end())
+        (*g++)->set_send_p(state);
+
+    Constructor::set_send_p(state);
+}
+
+void
+D4Group::intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator &eval*/)
+{
+    groupsIter g = d_groups.begin();
+    while (g != d_groups.end())
+        (*g++)->intern_data(checksum/*, dmr, eval*/);
+
+    // Specialize how the top-level variables in any Group are sent; include
+    // a checksum for them. A subset operation might make an interior set of
+    // variables, but the parent structure will still be present and the checksum
+    // will be computed for that structure. In other words, DAP4 does not try
+    // to sort out which variables are the 'real' top-level variables and instead
+    // simply computes the CRC for whatever appears as a variable in the root
+    // group.
+	for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
+		// Only send the stuff in the current subset.
+		if ((*i)->send_p()) {
+			checksum.Reset();
+
+			(*i)->intern_data(checksum/*, dmr, eval*/);
+
+			D4Attribute *a = new D4Attribute("DAP4_Checksum_CRC32", attr_str_c);
+		    ostringstream oss;
+		    oss.setf(ios::hex, ios::basefield);
+		    oss << setfill('0') << setw(8) << checksum.GetCrc32();
+		    a->add_value(oss.str());
+			(*i)->attributes()->add_attribute_nocopy(a);
+			DBG(cerr << "CRC32: " << oss.str() << " for " << (*i)->name() << endl);
+		}
+	}
+}
+
+/**
+ * @brief Serialize a Group
+ * @param m The DAP4 Stream Marshaller. This object serializes the data values and
+ * writes checksums (using CRC32) for the top level variables in every Group for which
+ * one or more variables are sent. The DAP4 Marshaller object can be made so that only
+ * the checksums are written.
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+D4Group::serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter)
+{
+#if 0
+    // This will call Constructor read which will, for everything but a Sequence,
+    // read all of the data in one shot. However, the serialize() methods for the
+    // Arrays, Structures, etc., also have read() calls in them and those can be
+    // used to control how long the data are in memory, e.g., limiting the lifetime
+    // of a large array and avoiding having overlapping arrays when they are not
+    // needed. For a sequence read() has different semantics. It is called once
+    // for every instance and the read_p flag is not used.
+    if (!read_p())
+        read();  // read() throws Error
+#endif
+
+    groupsIter g = d_groups.begin();
+    while (g != d_groups.end())
+        (*g++)->serialize(m, dmr, /*eval,*/ filter);
 
-    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)type_name().c_str()) < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
+    // Specialize how the top-level variables in any Group are sent; include
+    // a checksum for them. A subset operation might make an interior set of
+    // variables, but the parent structure will still be present and the checksum
+    // will be computed for that structure. In other words, DAP4 does not try
+    // to sort out which variables are the 'real' top-level variables and instead
+    // simply computes the CRC for whatever appears as a variable in the root
+    // group.
+	for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
+		// Only send the stuff in the current subset.
+		if ((*i)->send_p()) {
+			m.reset_checksum();
 
-    if (!name().empty())
-        if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
+			(*i)->serialize(m, dmr, /*eval,*/ filter);
+
+			DBG(cerr << "Wrote CRC32: " << m.get_checksum() << " for " << (*i)->name() << endl);
+			m.put_checksum();
+		}
+	}
+}
+
+void D4Group::deserialize(D4StreamUnMarshaller &um, DMR &dmr)
+{
+	groupsIter g = d_groups.begin();
+	while (g != d_groups.end())
+		(*g++)->deserialize(um, dmr);
+
+	// Specialize how the top-level variables in any Group are received; read
+	// their checksum and store the value in a magic attribute of the variable
+	for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
+		(*i)->deserialize(um, dmr);
+
+		D4Attribute *a = new D4Attribute("DAP4_Checksum_CRC32", attr_str_c);
+		string crc = um.get_checksum_str();
+		a->add_value(crc);
+		DBG(cerr << "Read CRC32: " << crc << " for " << (*i)->name() << endl);
+		(*i)->attributes()->add_attribute_nocopy(a);
+	}
+}
+
+void
+D4Group::print_dap4(XMLWriter &xml, bool constrained)
+{
+    if (!name().empty() && name() != "/") {
+        // For named groups, if constrained is true only print if this group
+        // has variables that are marked for transmission. For the root group
+        // this test is not made.
+        if (constrained && !send_p())
+            return;
+
+        if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) type_name().c_str()) < 0)
+            throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
+
+        if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*) name().c_str()) < 0)
             throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+    }
+
+    // dims
+    if (!dims()->empty())
+        dims()->print_dap4(xml, constrained);
 
-    // If the Group has Enumeration definitions
-    if (d_enums.size() > 0)
-        for_each(d_enums.begin(), d_enums.end(), PrintEnum(xml));
+    // enums
+    if (!enum_defs()->empty())
+        enum_defs()->print_dap4(xml, constrained);
 
-    // If it has attributes
-    if (get_attr_table().get_size() > 0)
-        get_attr_table().print_xml_writer(xml);
+    // variables
+    Constructor::Vars_iter v = var_begin();
+    while (v != var_end())
+        (*v++)->print_dap4(xml, constrained);
 
-    // If it has variables
-    if (var_begin() != var_end())
-        for_each(var_begin(), var_end(), PrintVariable(xml, constrained));
+    // attributes
+    attributes()->print_dap4(xml);
 
-    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
-        throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
+    // groups
+    groupsIter g = d_groups.begin();
+    while (g != d_groups.end())
+        (*g++)->print_dap4(xml, constrained);
+
+    if (!name().empty() && name() != "/") {
+        if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+            throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
+    }
 }
 
 } /* namespace libdap */
diff --git a/D4Group.h b/D4Group.h
index 91c1a17..2dfec5c 100644
--- a/D4Group.h
+++ b/D4Group.h
@@ -1,44 +1,142 @@
-/*
- * D4Group.h
- *
- *  Created on: Sep 27, 2012
- *      Author: jimg
- */
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
 #ifndef D4GROUP_H_
 #define D4GROUP_H_
 
+#include <string>
+
 #include "Constructor.h"
 #include "D4Dimensions.h"
-#include "D4EnumDef.h"
+#include "D4EnumDefs.h"
+
+class Crc32;
 
 namespace libdap {
 
+class BaseType;
+class Array;
+
+/** A DAP4 Group object. A Group is-a Constructor, so it inherits a set of
+ * BaseType objects and an attribute table, along with methods to search for
+ * variables by name where dots (.) in a fully qualified name serve as
+ * separators.
+ */
 class D4Group :public Constructor {
 private:
-    // I use the same object to define the dimensions (here) and to
-    // include them in the individual variables (in BaseType.h)
-    D4Dimensions d_dims;
+    // Note that because Constructor is a BaseType, this class inherits
+    // both a back pointer to its parent, an AttrTable and, directly from the
+    // Constructor class, a vector of BaseTypes.
 
-    // The Group object is a container for both variables and enumeration
-    // definitions.
-    vector<D4EnumDef*> d_enums;
+    // This instance of D4Dimensions holds the Group's definitions; the same
+    // class is used by Array to hold the actual dimensions for a variable.
+    D4Dimensions *d_dims;
+
+    // This holds the Group's enumeration definitions; a different class is
+    // used for the Enumeration type
+    D4EnumDefs *d_enum_defs;
+
+    // This is a pointer so that the factory class(es) that return pointers
+    // work as expected when making Groups.
+    vector<D4Group*> d_groups;
+
+    BaseType *m_find_map_source_helper(const string &name);
+
+protected:
+    void m_duplicate(const D4Group &g);
 
-    // TODO Must define m_duplicate so that d_enums are copied.
-    // Must be a deep copy
 public:
-    D4Group(const string &n);
-    D4Group(const string &n, const string &d);
+    typedef vector<D4Group*>::iterator groupsIter;
+    typedef vector<D4Group*>::const_iterator groupsCIter;
+
+    D4Group(const string &name);
+    D4Group(const string &name, const string &dataset);
 
     D4Group(const D4Group &rhs);
     virtual ~D4Group();
 
     D4Group &operator=(const D4Group &rhs);
-    virtual BaseType *ptr_duplicate();
+    virtual D4Group *ptr_duplicate();
+
+    /// Get the dimensions defined for this Group
+    D4Dimensions *dims() {
+    	// If not built yet, make one and set this as parent.
+        if (!d_dims) d_dims = new D4Dimensions(this);
+        return d_dims;
+    }
+
+    virtual std::string FQN() const;
+
+    D4Dimension *find_dim(const string &path);
+
+    Array *find_map_source(const string &path);
+
+    D4EnumDef *find_enum_def(const string &path);
+
+    /// Get  the enumerations defined for this Group
+    D4EnumDefs *enum_defs() {
+        if (!d_enum_defs) {
+        	d_enum_defs = new D4EnumDefs;
+        	d_enum_defs->set_parent(this);
+        }
+        return d_enum_defs;
+    }
+
+    BaseType *find_first_var_that_uses_dimension(D4Dimension *dim);
+    BaseType *find_first_var_that_uses_enumeration(D4EnumDef *enum_def);
+
+    BaseType *find_var(const string &name);
+
+    /// Get an iterator to the start of the values
+    groupsIter grp_begin() { return d_groups.begin(); }
+
+    /// Get an iterator to the end of the values
+    groupsIter grp_end() { return d_groups.end(); }
+
+    void add_group(const D4Group *g) {
+    	add_group_nocopy(new D4Group(*g));
+    }
+
+    void add_group_nocopy(D4Group *g) {
+    	g->set_parent(this);
+        d_groups.push_back(g);
+    }
+    void insert_group_nocopy(D4Group *g, groupsIter i) {
+    	g->set_parent(this);
+        d_groups.insert(i, g);
+    }
+
+    D4Group *find_child_grp(const string &grp_name);
+
+    long request_size(bool constrained);
+
+    virtual void set_send_p(bool state);
+    virtual void set_read_p(bool state);
 
-    void print_xml_writer(XMLWriter &xml, bool constrained);
+    // DAP4
+    virtual void intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator &eval*/);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
 
-    void add_enumeration_nocopy(D4EnumDef *enum_def);
+    void print_dap4(XMLWriter &xml, bool constrained = false);
 };
 
 } /* namespace libdap */
diff --git a/D4Maps.cc b/D4Maps.cc
index 56e33c1..384cf9a 100644
--- a/D4Maps.cc
+++ b/D4Maps.cc
@@ -1,23 +1,53 @@
-/*
- * D4Maps.cc
- *
- *  Created on: Sep 26, 2012
- *      Author: jimg
- */
+// -*- mode: c++; c-basic-offset:4 -*-
 
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include "XMLWriter.h"
+#include "InternalErr.h"
 #include "D4Maps.h"
 
-namespace libdap {
+using namespace libdap;
 
-D4Maps::D4Maps()
+void
+D4Map::print_dap4(XMLWriter &xml)
 {
-    // TODO Auto-generated constructor stub
+	if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Map") < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write Map element");
+
+	if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+
+	if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not end Map element");
 
 }
 
-D4Maps::~D4Maps()
+D4Maps&
+D4Maps::operator=(const D4Maps &rhs)
 {
-    // TODO Auto-generated destructor stub
+	if (this == &rhs) return *this;
+	m_duplicate(rhs);
+	return *this;
 }
-
-} /* namespace libdap */
diff --git a/D4Maps.h b/D4Maps.h
index fd79af4..5abce4a 100644
--- a/D4Maps.h
+++ b/D4Maps.h
@@ -1,9 +1,26 @@
-/*
- * D4Maps.h
- *
- *  Created on: Sep 26, 2012
- *      Author: jimg
- */
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
 #ifndef D4MAPS_H_
 #define D4MAPS_H_
@@ -15,28 +32,87 @@ using namespace std;
 
 namespace libdap {
 
+class Array;
+class XMLWriter;
+
+class D4Map {
+    std::string d_name;
+    Array *d_array;		// the actual map data; weak pointer
+    Array *d_parent;	// what array holds this map; weak pointer
+
+public:
+    D4Map() : d_name(""), d_array(0), d_parent(0) { }
+    D4Map(const string &name, Array *array, Array *parent = 0) : d_name(name), d_array(array), d_parent(parent) { }
+
+	virtual ~D4Map() { }
+
+	const string& name() const { return d_name; }
+	void set_name(const string& name) { d_name = name; }
+
+	const Array* array() const { return d_array; }
+	void set_array(Array* array) { d_array = array; }
+
+	/**
+	 * @brief The Array that holds this Map
+	 */
+	const Array* parent() const { return d_parent; }
+	void set_parent(Array* parent) { d_parent = parent; }
+
+	virtual void print_dap4(XMLWriter &xml);
+};
+
 /**
  * Maps in DAP4 are simply the names of Dimensions. When a dimensioned
- * variable (i.e., an array) also has 'maps' that array is a 'grid' in the
- * sense that the 'maps' define the domain of a sampled function.
- *
- * @todo Is this class needed?
+ * variable (i.e., an array) also has one or more 'maps,' then that
+ * array is a 'grid' (the 'maps' define the domain of a sampled function
+ * or a 'coverage').
  */
 class D4Maps {
+public:
+    typedef vector<D4Map*>::iterator D4MapsIter;
+    typedef vector<D4Map*>::const_iterator D4MapsCIter;
+
 private:
-    vector<string> d_names;
+	vector<D4Map*> d_maps;
+	Array *d_parent;	// Array these Maps belong to; weak pointer
+
+	void m_duplicate(const D4Maps &maps) {
+		d_parent = maps.d_parent;
+		for (D4MapsCIter ci = maps.d_maps.begin(), ce = maps.d_maps.end(); ci != ce; ++ci) {
+			d_maps.push_back(new D4Map(**ci));
+		}
+	}
 
 public:
-    D4Maps();
-    virtual ~D4Maps();
+    D4Maps() {}
+    D4Maps(Array* parent) : d_parent(parent) { }
+    D4Maps(const D4Maps &maps) { m_duplicate(maps); }
+    virtual ~D4Maps() {
+    	for (D4MapsIter i = d_maps.begin(), e = d_maps.end(); i != e; ++i)
+    		delete *i;
+    }
+
+    D4Maps &operator=(const D4Maps &rhs);
+
+    void add_map(D4Map *map) {
+    	d_maps.push_back(map);
+    	// if the Map parent is not set, do so now
+    	if (!d_maps.back()->parent())
+    		d_maps.back()->set_parent(d_parent);
+    }
+
+    D4Map* get_map(int i) { return d_maps.at(i); }
 
-    typedef vector<string>::iterator D4MapsIter;
+    D4MapsIter map_begin() { return d_maps.begin(); }
+    D4MapsIter map_end() { return d_maps.end(); }
 
-    void add_map(const string &map) { d_names.push_back(map); }
-    string get_map(int i) { return d_names.at(i); }
+    int size() const { return d_maps.size(); }
+    bool empty() const { return d_maps.empty(); }
 
-    D4MapsIter maps_begin() { return d_names.begin(); }
-    D4MapsIter maps_end() { return d_names.end(); }
+    virtual void print_dap4(XMLWriter &xml) {
+    	for (D4MapsIter i = d_maps.begin(), e = d_maps.end(); i != e; ++i)
+    		(*i)->print_dap4(xml);
+    }
 };
 
 } /* namespace libdap */
diff --git a/D4Opaque.cc b/D4Opaque.cc
new file mode 100644
index 0000000..5a1d5d5
--- /dev/null
+++ b/D4Opaque.cc
@@ -0,0 +1,158 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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., 51 Franklin D4Opaqueeet, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+
+#include "config.h"
+
+#include <sstream>
+#include <iterator>
+
+#include "D4Opaque.h"
+
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
+#include "util.h"
+#include "crc.h"
+
+#include "debug.h"
+
+using namespace std;
+
+namespace libdap {
+
+D4Opaque &
+D4Opaque::operator=(const D4Opaque &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    // Call BaseType::operator=
+    dynamic_cast<BaseType &>(*this) = rhs;
+
+    d_buf = rhs.d_buf;
+
+    return *this;
+}
+
+void
+D4Opaque::compute_checksum(Crc32 &checksum)
+{
+	checksum.AddData(&d_buf[0], d_buf.size());
+}
+
+void
+D4Opaque::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+    m.put_opaque_dap4( reinterpret_cast<char*>(&d_buf[0]), d_buf.size() ) ;
+}
+
+void
+D4Opaque::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+    um.get_opaque_dap4( d_buf ) ;
+}
+
+unsigned int
+D4Opaque::buf2val(void **val)
+{
+	assert(val);
+
+    // 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 vector<uint8_t>
+	// (i.e., dods_opaque) and assign d_buf's value to that storage.
+    if (!*val)
+        *val = new vector<uint8_t>;
+    else
+        *static_cast<vector<uint8_t>*>(*val) = d_buf;
+
+    return sizeof(vector<uint8_t>*);
+}
+
+unsigned int
+D4Opaque::val2buf(void *val, bool)
+{
+    assert(val);
+
+    d_buf = *static_cast<dods_opaque*>(val);
+
+    return sizeof(dods_opaque*);
+}
+
+/** 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
+D4Opaque::set_value(const dods_opaque &value)
+{
+    d_buf = value;
+    set_read_p(true);
+
+    return true;
+}
+
+/** Get the value of this instance.
+    @return The value. */
+D4Opaque::dods_opaque
+D4Opaque::value() const
+{
+    return d_buf;
+}
+
+void
+D4Opaque::print_val(ostream &out, string space, bool print_decl_p)
+{
+	if (print_decl_p) print_decl(out, space, false);
+
+	if (d_buf.size()) {
+		// end() - 1 is only OK if size() is > 0
+		std::ostream_iterator<unsigned int> out_it(out, ",");
+		std::copy(d_buf.begin(), d_buf.end() - 1, out_it);
+		out << (unsigned int) d_buf.back(); // can also use: *(d_buf.end()-1);
+	}
+
+	if (print_decl_p) out << ";" << endl;
+}
+
+void
+D4Opaque::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "D4Opaque::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    //strm << DapIndent::LMarg << "value: " << d_buf << endl ;
+    ostream_iterator<uint8_t> out_it (strm," ");
+    std::copy ( d_buf.begin(), d_buf.end(), out_it );
+
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/D4Opaque.h b/D4Opaque.h
new file mode 100644
index 0000000..b0f9893
--- /dev/null
+++ b/D4Opaque.h
@@ -0,0 +1,102 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _d4_opaque_h
+#define _d4_opaque_h 1
+
+#include <vector>
+
+#include "BaseType.h"
+#include "InternalErr.h"
+
+class Crc32;
+
+namespace libdap
+{
+
+class D4Opaque: public BaseType
+{
+public:
+	typedef std::vector<uint8_t> dods_opaque;
+
+protected:
+    dods_opaque d_buf;
+
+public:
+    D4Opaque(const std::string &n) : BaseType(n, dods_opaque_c), d_buf(0) { }
+    D4Opaque(const std::string &n, const std::string &d)  : BaseType(n, d, dods_opaque_c), d_buf(0) { }
+
+    virtual ~D4Opaque()  { }
+
+    D4Opaque(const D4Opaque &copy_from) : BaseType(copy_from) {
+        d_buf = copy_from.d_buf;
+    }
+
+    D4Opaque &operator=(const D4Opaque &rhs);
+
+    virtual BaseType *ptr_duplicate() {  return new D4Opaque(*this); }
+
+    virtual unsigned int width(bool = false) const { return sizeof(vector<uint8_t>); }
+
+    // Return the length of the stored data or zero if no string has been
+    // stored in the instance's internal buffer.
+    virtual int length() const { return d_buf.size(); }
+
+    // DAP2
+    virtual bool serialize(ConstraintEvaluator &, DDS &, Marshaller &, bool = true) {
+    	throw InternalErr(__FILE__, __LINE__, "Unimplemented method");
+    }
+    virtual bool deserialize(UnMarshaller &, DDS *, bool = false) {
+    	throw InternalErr(__FILE__, __LINE__, "Unimplemented method");
+    }
+
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual bool set_value(const dods_opaque &value);
+    virtual dods_opaque value() const;
+
+    virtual void print_val(FILE *, std::string = "", bool = true)  {
+    	throw InternalErr(__FILE__, __LINE__, "Unimplemented method");
+    }
+    virtual void print_val(std::ostream &out, std::string space = "", bool print_decl_p = true);
+
+    //virtual void print_dap4(XMLWriter &xml, bool constrained = false);
+
+    virtual bool ops(BaseType *, int) {
+        throw InternalErr(__FILE__, __LINE__, "Unimplemented method");
+    }
+
+    virtual void dump(std::ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _d4_opaque_h
+
diff --git a/D4ParserSax2.cc b/D4ParserSax2.cc
index be6f17f..f3d5ff9 100644
--- a/D4ParserSax2.cc
+++ b/D4ParserSax2.cc
@@ -24,51 +24,40 @@
 
 #include "config.h"
 
-#define DODS_DEBUG 1
-#define DODS_DEBUG2 1
+//#define DODS_DEBUG 1
 
 #include <iostream>
 #include <sstream>
 
 #include <cstring>
 #include <cstdarg>
+#include <cassert>
 
-#include "BaseType.h"
-#include "Byte.h"
-#include "Int8.h"
-#include "Int16.h"
-#include "UInt16.h"
-#include "Int32.h"
-#include "UInt32.h"
-#include "Int64.h"
-#include "UInt64.h"
-
-#include "Float32.h"
-#include "Float64.h"
-
-#include "Str.h"
-#include "Url.h"
+#include <libxml/parserInternals.h>
 
-#include "Constructor.h"
+#include "DMR.h"
 
+#include "BaseType.h"
+#include "Array.h"
 #include "D4Group.h"
+#include "D4Attributes.h"
+#include "D4Maps.h"
+#include "D4Enum.h"
 
-#include "Array.h"
-#include "Structure.h"
-#include "Sequence.h"
-#include "Grid.h"
+#include "D4BaseTypeFactory.h"
 
 #include "D4ParserSax2.h"
 
 #include "util.h"
-// #include "mime_util.h"
 #include "debug.h"
 
 namespace libdap {
 
-static const not_used char *states[] = {
+static const char *states[] = {
         "parser_start",
 
+        "inside_dataset",
+
         // inside_group is the state just after parsing the start of a Group
         // element.
         "inside_group",
@@ -81,285 +70,311 @@ static const not_used char *states[] = {
         "inside_enum_def",
         "inside_enum_const",
 
+        "inside_dim_def",
+
         // This covers Byte, ..., Url, Opaque
         "inside_simple_type",
 
-        "inside_array",
-        "inside_dimension",
-
-        "inside_grid",
+        // "inside_array",
+        "inside_dim",
         "inside_map",
 
-        "inside_structure",
-        "inside_sequence",
+        "inside_constructor",
 
         "parser_unknown",
-        "parser_error" };
-
-// Glue the BaseTypeFactory to the enum-based factory defined statically
-// here.
-
-BaseType *D4ParserSax2::factory(Type t, const string & name)
-{
-    switch (t) {
-        case dods_byte_c:
-            return d_factory->NewByte(name);
-        case dods_uint8_c:
-            return d_factory->NewUInt8(name);
-        case dods_int8_c:
-            return d_factory->NewInt8(name);
-        case dods_int16_c:
-            return d_factory->NewInt16(name);
-        case dods_uint16_c:
-            return d_factory->NewUInt16(name);
-        case dods_int32_c:
-            return d_factory->NewInt32(name);
-        case dods_uint32_c:
-            return d_factory->NewUInt32(name);
-        case dods_int64_c:
-            return d_factory->NewInt64(name);
-        case dods_uint64_c:
-            return d_factory->NewUInt64(name);
-        case dods_float32_c:
-            return d_factory->NewFloat32(name);
-        case dods_float64_c:
-            return d_factory->NewFloat64(name);
-        case dods_str_c:
-            return d_factory->NewStr(name);
-        case dods_url_c:
-            return d_factory->NewUrl(name);
-        case dods_url4_c:
-            return d_factory->NewURL(name);
-        case dods_array_c:
-            return d_factory->NewArray(name);
-        case dods_structure_c:
-            return d_factory->NewStructure(name);
-        case dods_sequence_c:
-            return d_factory->NewSequence(name);
-        case dods_grid_c:
-            return d_factory->NewGrid(name);
-        case dods_group_c:
-            return d_factory->NewGroup(name);
-        default:
-            return 0;
-    }
-}
+        "parser_error",
+        "parser_fatal_error",
 
-static bool is_valid_enum_value(const Type &t, long long value)
-{
-    switch (t) {
-        case dods_int8_c:
-            return (value >= DODS_SCHAR_MIN && value <= DODS_SCHAR_MAX);
-        case dods_byte_c:
-        case dods_uint8_c:
-            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UCHAR_MAX);
-        case dods_int16_c:
-            return (value >= DODS_SHRT_MIN && value <= DODS_SHRT_MAX);
-        case dods_uint16_c:
-            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_USHRT_MAX);
-        case dods_int32_c:
-            return (value >= DODS_INT_MIN && value <= DODS_INT_MAX);
-        case dods_uint32_c:
-            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UINT_MAX);
-        case dods_int64_c:
-            return (value >= DODS_LLONG_MIN && value <= DODS_LLONG_MAX);
-        case dods_uint64_c:
-            return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_ULLONG_MAX);
-        default:
-            return false;
-    }
-}
+        "parser_end"
+};
 
 static bool is_not(const char *name, const char *tag)
 {
     return strcmp(name, tag) != 0;
 }
 
-void D4ParserSax2::set_state(D4ParserSax2::ParseState state)
+/** @brief Return the current Enumeration definition
+ * Allocate the Enumeration definition if needed and return it. Once parsing the current
+ * enumeration definition is complete, the pointer allocated/returned by this method will
+ * be copied into the current Group and this internal storage will be 'reset' using
+ * clear_enum_def().
+ *
+ * @return
+ */
+D4EnumDef *
+D4ParserSax2::enum_def()
 {
-    s.push(state);
-}
+    if (!d_enum_def) d_enum_def = new D4EnumDef;
 
-D4ParserSax2::ParseState D4ParserSax2::get_state() const
-{
-    return s.top();
+    return d_enum_def;
 }
 
-void D4ParserSax2::pop_state()
-{
-    s.pop();
+/** @brief Return the current Dimension definition
+ * Allocate the Dimension definition if needed and return it.
+ * @see enum_def() for an explanation of how this is used by the parser.
+ *
+ * @return
+ */
+D4Dimension *
+D4ParserSax2::dim_def()    {
+    if (!d_dim_def) d_dim_def = new D4Dimension;
+
+    return d_dim_def;
 }
 
 /** Dump XML attributes to local store so they can be easily manipulated.
- Attribute names are always folded to lower case.
- @param attributes The XML attribute array
- @param nb_attributes Teh number of attributes */
+ * XML attribute names are always folded to lower case.
+ * @param attributes The XML attribute array
+ * @param nb_attributes The number of attributes
+ */
 void D4ParserSax2::transfer_xml_attrs(const xmlChar **attributes, int nb_attributes)
 {
     if (!xml_attrs.empty())
         xml_attrs.clear(); // erase old attributes
 
+    // Make a value using the attribute name and the prefix, namespace URI
+    // and the value. The prefix might be null.
     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.
-        xml_attrs.insert(map<string, XMLAttribute>::value_type(string((const char *) attributes[index]),
-                        XMLAttribute(attributes + index + 1)));
+        xml_attrs.insert(map<string, XMLAttribute>::value_type(string((const char *)attributes[index]),
+                                                               XMLAttribute(attributes + index + 1)));
 
-        DBG(cerr << "Attribute '" << (const char *)attributes[index] << "': "
+        DBG(cerr << "XML Attribute '" << (const char *)attributes[index] << "': "
                 << xml_attrs[(const char *)attributes[index]].value << endl);
     }
 }
 
+/** Transfer the XML namespaces to the local store so they can be manipulated
+ * more easily.
+ *
+ * @param namespaces Array of xmlChar*
+ * @param nb_namespaces The number of namespaces in the array.
+ */
 void D4ParserSax2::transfer_xml_ns(const xmlChar **namespaces, int nb_namespaces)
 {
+    // make a value with the prefix and namespace URI. The prefix might be null.
     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]));
+        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 */
+/** Is a required XML 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, otherwise
+ * it sets the global error state and returns false.
+ */
 bool D4ParserSax2::check_required_attribute(const string & attr)
 {
-    map<string, XMLAttribute>::iterator i = xml_attrs.find(attr);
-    if (i == xml_attrs.end())
-        ddx_fatal_error(this, "Required attribute '%s' not found.", attr.c_str());
-    return true;
+    if (xml_attrs.find(attr) == xml_attrs.end()) {
+        dmr_error(this, "Required attribute '%s' not found.", attr.c_str());
+        return false;
+    }
+    else
+        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. */
+/** Is a XML 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 D4ParserSax2::check_attribute(const string & attr)
 {
     return (xml_attrs.find(attr) != xml_attrs.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 D4ParserSax2::process_attribute_helper(const xmlChar **attrs, int nb_attributes)
+bool D4ParserSax2::process_dimension_def(const char *name, 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 (xml_attrs["type"].value == "Container") {
-        set_state(inside_attribute_container);
+    if (is_not(name, "Dimension"))
+        return false;
 
-        AttrTable *child;
-        AttrTable *parent = at_stack.top();
+    transfer_xml_attrs(attrs, nb_attributes);
 
-        child = parent->append_container(xml_attrs["name"].value);
-        at_stack.push(child); // save.
-        DBG2(cerr << "Pushing at" << endl);
+    if (!(check_required_attribute("name") && check_required_attribute("size"))) {
+        dmr_error(this, "The required attribute 'name' or 'size' was missing from a Dimension element.");
+        return false;
     }
-    else if (xml_attrs["type"].value == "OtherXML") {
-        set_state(inside_other_xml_attribute);
 
-        dods_attr_name = xml_attrs["name"].value;
-        dods_attr_type = xml_attrs["type"].value;
+    // This getter (dim_def) allocates a new object if needed.
+    dim_def()->set_name(xml_attrs["name"].value);
+    try {
+        dim_def()->set_size(xml_attrs["size"].value);
     }
-    else {
-        set_state(inside_attribute);
-
-        dods_attr_name = xml_attrs["name"].value;
-        dods_attr_type = xml_attrs["type"].value;
+    catch (Error &e) {
+        dmr_error(this, e.get_error_message().c_str());
+        return false;
     }
+
+    return true;
 }
 
-/** Given that an \c Enumeration tag has just been read...
+/**
+ * @brief Process a Dim element.
+ * If a Dim element is found, the current variable is an Array. If the BaseType
+ * on the TOS is not already an Array, make it one. Append the dimension
+ * information to the Array variable on the TOS.
+ *
+ * @note Dim elements can have two attributes: name or size. The latter defines
+ * an 'anonymous' dimension (one without a name that does not reference a
+ * shared dimension object. If the \c name attribute is used, then the shared
+ * dimension used is the one defined by the enclosing group or found using the
+ * fully qualified name. The \name and \c size attributes are mutually exclusive.
+ *
+ * @param name XML element name; must be Dim
+ * @param attrs XML Attributes
+ * @param nb_attributes The number of XML Attributes
+ * @return True if the element is a Dim, false otherwise.
+ */
+bool D4ParserSax2::process_dimension(const char *name, const xmlChar **attrs, int nb_attributes)
+{
+    if (is_not(name, "Dim"))
+        return false;
+
+    transfer_xml_attrs(attrs, nb_attributes);
 
+	if (check_attribute("size") && check_attribute("name")) {
+		dmr_error(this, "Only one of 'size' and 'name' are allowed in a Dim element, but both were used.");
+		return false;
+	}
+	if (!(check_attribute("size") || check_attribute("name"))) {
+		dmr_error(this, "Either 'size' or 'name' must be used in a Dim element.");
+		return false;
+	}
+
+	if (!top_basetype()->is_vector_type()) {
+		// Make the top BaseType* an array
+		BaseType *b = top_basetype();
+		pop_basetype();
+
+		Array *a = static_cast<Array*>(dmr()->factory()->NewVariable(dods_array_c, b->name()));
+		a->set_is_dap4(true);
+		a->add_var_nocopy(b);
+		a->set_attributes_nocopy(b->attributes());
+		// trick: instead of popping b's attributes, copying them and then pushing
+		// a's copy, just move the pointer (but make sure there's only one object that
+		// references that pointer).
+		b->set_attributes_nocopy(0);
+
+		push_basetype(a);
+	}
+
+	assert(top_basetype()->is_vector_type());
+
+	Array *a = static_cast<Array*>(top_basetype());
+    if (check_attribute("size")) {
+    	a->append_dim(atoi(xml_attrs["size"].value.c_str())); // low budget code for now. jhrg 8/20/13
+        return true;
+    }
+    else if (check_attribute("name")) {
+    	string name = xml_attrs["name"].value;
+
+    	D4Dimension *dim = 0;
+    	if (name[0] == '/')		// lookup the Dimension in the root group
+    		dim = dmr()->root()->find_dim(name);
+    	else					// get enclosing Group and lookup Dimension there
+    		dim = top_group()->find_dim(name);
+
+    	if (!dim)
+    		throw Error("The dimension '" + name + "' was not found while parsing the variable '" + a->name() + "'.");
+    	a->append_dim(dim);
+    	return true;
+    }
+
+    return false;
+}
 
- @param attrs The array of XML attribute values */
-void D4ParserSax2::process_enum_def_helper(const xmlChar **attrs, int nb_attributes)
+bool D4ParserSax2::process_map(const char *name, const xmlChar **attrs, int nb_attributes)
 {
-    // These methods set the state to parser_error if a problem is found.
+    if (is_not(name, "Map"))
+        return false;
+
     transfer_xml_attrs(attrs, nb_attributes);
 
-    bool error = !(check_required_attribute(string("name"))
-                   && check_required_attribute(string("basetype")));
-    if (error)
-        return;
+	if (!check_attribute("name")) {
+		dmr_error(this, "The 'name' attribute must be used in a Map element.");
+		return false;
+	}
 
-    Type t = get_type(xml_attrs["basetype"].value.c_str());
-    if (!is_integer_type(t)) {
-        ddx_fatal_error(this, "Error: The Enumeration '%s' must have an integer type, instead the type '%s' was used.",
-                xml_attrs["name"].value.c_str(), xml_attrs["basetype"].value.c_str());
-        // So that the parse can continue, make the type UInt64
-        t = dods_uint64_c;
-    }
+	if (!top_basetype()->is_vector_type()) {
+		// Make the top BaseType* an array
+		BaseType *b = top_basetype();
+		pop_basetype();
 
-    d_enum_def = new D4EnumDef(xml_attrs["name"].value, t);
+		Array *a = static_cast<Array*>(dmr()->factory()->NewVariable(dods_array_c, b->name()));
+		a->set_is_dap4(true);
+		a->add_var_nocopy(b);
+		a->set_attributes_nocopy(b->attributes());
+		// trick: instead of popping b's attributes, copying them and then pushing
+		// a's copy, just move the pointer (but make sure there's only one object that
+		// references that pointer).
+		b->set_attributes_nocopy(0);
 
-    set_state(inside_enum_def);
-}
+		push_basetype(a);
+	}
 
-/** Given that an \c Enumeration tag has just been read...
+	assert(top_basetype()->is_vector_type());
 
+	Array *a = static_cast<Array*>(top_basetype());
 
- @param attrs The array of XML attribute values */
-void D4ParserSax2::process_enum_const_helper(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);
+	string map_name = xml_attrs["name"].value;
+	if (xml_attrs["name"].value[0] != '/')
+		map_name = top_group()->FQN() + map_name;
 
-    bool error = !(check_required_attribute(string("name"))
-                   && check_required_attribute(string("value")));
-    if (error)
-        return;
+    Array *map_source = 0;	// The array variable that holds the data for the Map
 
-    istringstream iss(xml_attrs["value"].value);
-    long long value = 0;
-    iss >> skipws >> value;
-    if (iss.fail() || iss.bad()) {
-        ddx_fatal_error(this, "Error: Expected an integer value for an Enumeration constant, got '%s' instead.",
-                xml_attrs["value"].value.c_str());
-    }
-    else if (!is_valid_enum_value(d_enum_def->get_type(), value))
-        ddx_fatal_error(this, "Error: In an Enumeration constant, the value '%s' cannot fit in a variable of type '%s'.",
-                xml_attrs["value"].value.c_str(), type_name(d_enum_def->get_type()).c_str());
+	if (map_name[0] == '/')		// lookup the Map in the root group
+		map_source = dmr()->root()->find_map_source(map_name);
+	else					// get enclosing Group and lookup Map there
+		map_source = top_group()->find_map_source(map_name);
 
-    else {
-        d_enum_def->add_value(xml_attrs["name"].value, value);
-    }
+	if (!map_source)
+		throw Error("The Map '" + map_name + "' was not found while parsing the variable '" + a->name() + "'.");
+
+	a->maps()->add_map(new D4Map(map_name, map_source));
 
-    set_state(inside_enum_const);
+	return true;
 }
 
-/** 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 D4ParserSax2::process_dimension(const xmlChar **attrs, int nb_attributes)
+bool D4ParserSax2::process_group(const char *name, const xmlChar **attrs, int nb_attributes)
 {
+    if (is_not(name, "Group"))
+        return false;
+
     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(xml_attrs["size"].value.c_str()), xml_attrs["name"].value);
+    if (!check_required_attribute("name")) {
+        dmr_error(this, "The required attribute 'name' was missing from a Group element.");
+        return false;
     }
+
+    BaseType *btp = dmr()->factory()->NewVariable(dods_group_c, xml_attrs["name"].value);
+    if (!btp) {
+        dmr_fatal_error(this, "Could not instantiate the Group '%s'.", xml_attrs["name"].value.c_str());
+        return false;
+    }
+
+    D4Group *grp = static_cast<D4Group*>(btp);
+
+    // Need to set this to get the D4Attribute behavior in the type classes
+    // shared between DAP2 and DAP4. jhrg 4/18/13
+    grp->set_is_dap4(true);
+
+    // link it up and change the current group
+    D4Group *parent = top_group();
+	if (!parent) {
+		dmr_fatal_error(this, "No Group on the Group stack.");
+		return false;
+	}
+
+	grp->set_parent(parent);
+	parent->add_group_nocopy(grp);
+
+    push_group(grp);
+    push_attributes(grp->attributes());
+    return true;
 }
 
 /** Check to see if the current tag is either an \c Attribute or an \c Alias
@@ -370,13 +385,48 @@ void D4ParserSax2::process_dimension(const xmlChar **attrs, int nb_attributes)
  @return True if the tag was an \c Attribute or \c Alias tag */
 inline bool D4ParserSax2::process_attribute(const char *name, const xmlChar **attrs, int nb_attributes)
 {
-    if (strcmp(name, "Attribute") == 0) {
-        process_attribute_helper(attrs, nb_attributes);
-        // next state: inside_attribtue or inside_attribute_container
-        return true;
+    if (is_not(name, "Attribute"))
+        return false;
+
+    // These methods set the state to parser_error if a problem is found.
+    transfer_xml_attrs(attrs, nb_attributes);
+
+    // add error
+    if (!(check_required_attribute(string("name")) && check_required_attribute(string("type")))) {
+        dmr_error(this, "The required attribute 'name' or 'type' was missing from an Attribute element.");
+        return false;
     }
 
-    return false;
+    if (xml_attrs["type"].value == "Container") {
+        push_state(inside_attribute_container);
+
+        DBG(cerr << "Pushing attribute container " << xml_attrs["name"].value << endl);
+        D4Attribute *child = new D4Attribute(xml_attrs["name"].value, attr_container_c);
+
+        D4Attributes *tos = top_attributes();
+        // add return
+        if (!tos) {
+            dmr_fatal_error(this, "Expected an Attribute container on the top of the attribute stack.");
+            return false;
+        }
+
+        tos->add_attribute_nocopy(child);
+        push_attributes(child->attributes());
+    }
+    else if (xml_attrs["type"].value == "OtherXML") {
+        push_state(inside_other_xml_attribute);
+
+        dods_attr_name = xml_attrs["name"].value;
+        dods_attr_type = xml_attrs["type"].value;
+    }
+    else {
+        push_state(inside_attribute);
+
+        dods_attr_name = xml_attrs["name"].value;
+        dods_attr_type = xml_attrs["type"].value;
+    }
+
+    return true;
 }
 
 /** Check to see if the current tag is an \c Enumeration start tag.
@@ -386,24 +436,66 @@ inline bool D4ParserSax2::process_attribute(const char *name, const xmlChar **at
  @return True if the tag was an \c Enumeration */
 inline bool D4ParserSax2::process_enum_def(const char *name, const xmlChar **attrs, int nb_attributes)
 {
-    if (strcmp(name, "Enumeration") == 0) {
-        process_enum_def_helper(attrs, nb_attributes);
-        // next state: inside_enum_def
-        return true;
+    if (is_not(name, "Enumeration"))
+        return false;
+
+    transfer_xml_attrs(attrs, nb_attributes);
+
+    if (!(check_required_attribute("name") && check_required_attribute("basetype"))) {
+        dmr_error(this, "The required attribute 'name' or 'basetype' was missing from an Enumeration element.");
+        return false;
     }
 
-    return false;
+    Type t = get_type(xml_attrs["basetype"].value.c_str());
+    if (!is_integer_type(t)) {
+        dmr_error(this, "The Enumeration '%s' must have an integer type, instead the type '%s' was used.",
+                xml_attrs["name"].value.c_str(), xml_attrs["basetype"].value.c_str());
+        return false;
+    }
+
+    // This getter allocates a new object if needed.
+    string enum_def_path = xml_attrs["name"].value;
+#if 0
+	// Use FQNs when things are referenced, not when they are defined
+    if (xml_attrs["name"].value[0] != '/')
+    	enum_def_path = top_group()->FQN() + enum_def_path;
+#endif
+    enum_def()->set_name(enum_def_path);
+    enum_def()->set_type(t);
+
+    return true;
 }
 
 inline bool D4ParserSax2::process_enum_const(const char *name, const xmlChar **attrs, int nb_attributes)
 {
-    if (strcmp(name, "EnumConst") == 0) {
-        process_enum_const_helper(attrs, nb_attributes);
-        // next state: inside_enum_const
-        return true;
+    if (is_not(name, "EnumConst"))
+        return false;
+
+    // These methods set the state to parser_error if a problem is found.
+    transfer_xml_attrs(attrs, nb_attributes);
+
+    if (!(check_required_attribute("name") && check_required_attribute("value"))) {
+        dmr_error(this, "The required attribute 'name' or 'value' was missing from an EnumConst element.");
+        return false;
     }
 
-    return false;
+    istringstream iss(xml_attrs["value"].value);
+    long long value = 0;
+    iss >> skipws >> value;
+    if (iss.fail() || iss.bad()) {
+        dmr_error(this, "Expected an integer value for an Enumeration constant, got '%s' instead.",
+                xml_attrs["value"].value.c_str());
+    }
+    else if (!enum_def()->is_valid_enum_value(value)) {
+        dmr_error(this, "In an Enumeration constant, the value '%s' cannot fit in a variable of type '%s'.",
+                xml_attrs["value"].value.c_str(), D4type_name(d_enum_def->type()).c_str());
+    }
+    else {
+        // unfortunate choice of names... args are 'label' and 'value'
+        enum_def()->add_value(xml_attrs["name"].value, value);
+    }
+
+    return true;
 }
 
 /** Check to see if the current element is the start of a variable declaration.
@@ -418,16 +510,20 @@ inline bool D4ParserSax2::process_variable(const char *name, const xmlChar **att
         process_variable_helper(t, inside_simple_type, attrs, nb_attributes);
         return true;
     }
-    else if (strcmp(name, "Structure") == 0) {
-        process_variable_helper(dods_structure_c, inside_structure, attrs, nb_attributes);
-        return true;
-    }
-    else if (strcmp(name, "Sequence") == 0) {
-        process_variable_helper(dods_sequence_c, inside_sequence, attrs, nb_attributes);
-        return true;
+    else {
+    	switch(t) {
+    	case dods_structure_c:
+            process_variable_helper(t, inside_constructor, attrs, nb_attributes);
+            return true;
+
+    	case dods_sequence_c:
+            process_variable_helper(t, inside_constructor, attrs, nb_attributes);
+            return true;
+
+    	default:
+    		return false;
+    	}
     }
-
-    return false;
 }
 
 /** Given that a tag which opens a variable declaration has just been read,
@@ -441,58 +537,34 @@ void D4ParserSax2::process_variable_helper(Type t, ParseState s, const xmlChar *
 {
     transfer_xml_attrs(attrs, nb_attributes);
 
-    set_state(s);
-
-    // TODO Arrays in DAP2 were not required to have names. DAP4 is going to
-    // need a different parsing logic, but we'll come to that...
-    if (check_required_attribute("name")) { // throws on error/false
-        BaseType *btp = factory(t, xml_attrs["name"].value);
-        if (!btp)
-            ddx_fatal_error(this, "Internal parser error; could not instantiate the variable '%s'.",
-                    xml_attrs["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());
-    }
-}
-
-void D4ParserSax2::finish_variable(const char *tag, Type t, const char *expected)
-{
-    if (strcmp(tag, expected) != 0) {
-        D4ParserSax2::ddx_fatal_error(this, "Expected an end tag for a %s; found '%s' instead.", expected, tag);
-        return;
-    }
+    if (check_required_attribute("name")) {
+        BaseType *btp = dmr()->factory()->NewVariable(t, xml_attrs["name"].value);
+        if (!btp) {
+            dmr_fatal_error(this, "Could not instantiate the variable '%s'.", xml_attrs["name"].value.c_str());
+            return;
+        }
 
-    pop_state();
+        if ((t == dods_enum_c) && check_required_attribute("enum")) {
+            D4EnumDef *enum_def = 0;
+            string enum_path = xml_attrs["enum"].value;
+			if (enum_path[0] == '/')
+                enum_def = dmr()->root()->find_enum_def(enum_path);
+            else
+                enum_def = top_group()->find_enum_def(enum_path);
 
-    BaseType *btp = bt_stack.top();
+            if (!enum_def)
+                dmr_fatal_error(this, "Could not find the Enumeration definition '%s'.", enum_path.c_str());
 
-    bt_stack.pop();
-    at_stack.pop();
+            static_cast<D4Enum*>(btp)->set_enumeration(enum_def);
+        }
 
-    if (btp->type() != t) {
-        D4ParserSax2::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) {
-        D4ParserSax2::ddx_fatal_error(this, "No dimension element included in the Array '%s'.", btp->name().c_str());
-        return;
-    }
+        btp->set_is_dap4(true); // see comment above
+        push_basetype(btp);
 
-    BaseType *parent = bt_stack.top();
+        push_attributes(btp->attributes());
 
-    if (!(parent->is_vector_type() || parent->is_constructor_type())) {
-        D4ParserSax2::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;
+        push_state(s);
     }
-
-    parent->add_var(btp);
 }
 
 /** @name SAX Parser Callbacks
@@ -501,134 +573,136 @@ void D4ParserSax2::finish_variable(const char *tag, Type t, const char *expected
  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 D4ParserSax2::ddx_start_document(void * p)
+void D4ParserSax2::dmr_start_document(void * p)
 {
     D4ParserSax2 *parser = static_cast<D4ParserSax2*>(p);
     parser->error_msg = "";
     parser->char_data = "";
 
-    parser->set_state(parser_start);
+    // Set this in intern_helper so that the loop test for the parser_end
+    // state works for the first iteration. It seems like XMLParseChunk calls this
+    // function on it's first run. jhrg 9/16/13
+    // parser->push_state(parser_start);
+
+    parser->push_attributes(parser->dmr()->root()->attributes());
 
-    DBG2(cerr << "Parser state: " << states[parser->get_state()] << endl);
+    if (parser->debug()) cerr << "Parser start state: " << states[parser->get_state()] << endl;
 }
 
 /** Clean up after finishing a parse.
  @param p The SAX parser  */
-void D4ParserSax2::ddx_end_document(void * p)
+void D4ParserSax2::dmr_end_document(void * p)
 {
     D4ParserSax2 *parser = static_cast<D4ParserSax2*>(p);
 
-    DBG2(cerr << "Ending state == " << states[parser->get_state()] << endl);
+    if (parser->debug()) cerr << "Parser end state: " << states[parser->get_state()] << endl;
 
-    if (parser->get_state() != parser_start)
-        D4ParserSax2::ddx_fatal_error(parser, "The document contained unbalanced tags.");
+    if (parser->get_state() != parser_end)
+        D4ParserSax2::dmr_error(parser, "The document contained unbalanced tags.");
 
     // If we've found any sort of error, don't make the DMR; intern() will
     // take care of the error.
-    if (parser->get_state() == parser_error)
+    if (parser->get_state() == parser_error || parser->get_state() == parser_fatal_error)
         return;
 
-    // TODO Decide to remove the outer Group or leave it in place and
-    // modify print_xml_writer() so that the DMR is correct.
+    if (!parser->empty_basetype() || parser->empty_group())
+    	D4ParserSax2::dmr_error(parser, "The document did not contain a valid root Group or contained unbalanced tags.");
 
-    parser->dds->add_var_nocopy(parser->bt_stack.top());
-    parser->bt_stack.pop();
+    parser->pop_group();     // leave the stack 'clean'
+    parser->pop_attributes();
 }
 
-void D4ParserSax2::ddx_start_element(void *p, const xmlChar *l, const xmlChar *prefix, const xmlChar *URI,
+void D4ParserSax2::dmr_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)
 {
     D4ParserSax2 *parser = static_cast<D4ParserSax2*>(p);
     const char *localname = (const char *) l;
 
-    DBG2(cerr << "start element: " << localname << ", state: " << states[parser->get_state()] << endl);
+    if (parser->debug()) cerr << "Start element " << localname << " (state " << states[parser->get_state()] << ")" << endl;
 
     switch (parser->get_state()) {
         case parser_start:
-            if (strcmp(localname, "Group") == 0) {
+            if (is_not(localname, "Dataset"))
+                D4ParserSax2::dmr_error(parser, "Expected DMR to start with a Dataset element; found '%s' instead.", localname);
 
-                parser->set_state(inside_group);
+            parser->root_ns = URI ? (const char *) URI : "";
+            parser->transfer_xml_attrs(attributes, nb_attributes);
 
-                parser->root_ns = URI ? (const char *) URI : "";
-                parser->transfer_xml_attrs(attributes, nb_attributes);
+            if (parser->check_required_attribute(string("name")))
+                parser->dmr()->set_name(parser->xml_attrs["name"].value);
 
-                // Set values in/for the DDS
-                if (parser->check_required_attribute(string("name")))
-                    parser->dds->set_dataset_name(parser->xml_attrs["name"].value);
+            if (parser->check_attribute("dapVersion"))
+                parser->dmr()->set_dap_version(parser->xml_attrs["dapVersion"].value);
 
-                if (parser->check_attribute("dapVersion"))
-                    parser->dds->set_dap_version(parser->xml_attrs["dapVersion"].value);
+            if (parser->check_attribute("dmrVersion"))
+                parser->dmr()->set_dmr_version(parser->xml_attrs["dmrVersion"].value);
 
-                // FIXME no way to record DMR version information
-#if 0
-                if (parser->check_attribute("dmrVersion"))
-                    parser->dds->set_dap_version(parser->xml_attrs["dmrVersion"].value);
-#endif
-                if (parser->check_attribute("base"))
-                    parser->dds->set_request_xml_base(parser->xml_attrs["base"].value);
+            if (parser->check_attribute("base"))
+                parser->dmr()->set_request_xml_base(parser->xml_attrs["base"].value);
 
-                if (!parser->root_ns.empty())
-                    parser->dds->set_namespace(parser->root_ns);
+            if (!parser->root_ns.empty())
+                parser->dmr()->set_namespace(parser->root_ns);
+
+            // Push the root Group on the stack
+            parser->push_group(parser->dmr()->root());
+
+            parser->push_state(inside_dataset);
 
-                // Set name of the Group; push on stack
-                BaseType *btp = parser->factory(dods_group_c, "root");
-                parser->bt_stack.push(btp);
-                parser->at_stack.push(&btp->get_attr_table());
-            }
-            else
-                D4ParserSax2::ddx_fatal_error(parser,
-                        "Expected DMR to start with a Group element; found '%s' instead.", localname);
             break;
 
-            // The state 'inside_group' means we have just parsed the start
-            // of a Group element, but none of the child elements
+            // Both inside dataset and inside group can have the same stuff.
+            // The difference is that the Dataset holds the root group, which
+            // must be present; other groups are optional
+        case inside_dataset:
         case inside_group:
-            // TODO Add Dimension and Group
-            if (parser->process_attribute(localname, attributes, nb_attributes))
-                break;
+            if (parser->process_enum_def(localname, attributes, nb_attributes))
+                parser->push_state(inside_enum_def);
+            else if (parser->process_dimension_def(localname, attributes, nb_attributes))
+                parser->push_state(inside_dim_def);
+            else if (parser->process_group(localname, attributes, nb_attributes))
+                parser->push_state(inside_group);
             else if (parser->process_variable(localname, attributes, nb_attributes))
-                break;
-            else if (parser->process_enum_def(localname, attributes, nb_attributes))
+                // This will push either inside_simple_type or inside_structure
+                // onto the parser state stack.
+               break;
+            else if (parser->process_attribute(localname, attributes, nb_attributes))
+                // This will push either inside_attribute, inside_attribute_container
+                // or inside_otherxml_attribute onto the parser state stack
                 break;
             else
-                D4ParserSax2::ddx_fatal_error(parser,
-                        "Expected an Attribute,  or variable element; found '%s' instead.", localname);
+                D4ParserSax2::dmr_error(parser, "Expected an Attribute, Enumeration, Dimension, Group or variable element; found '%s' instead.", localname);
             break;
 
         case inside_attribute_container:
             if (parser->process_attribute(localname, attributes, nb_attributes))
                 break;
             else
-                D4ParserSax2::ddx_fatal_error(parser, "Expected an Attribute or Alias element; found '%s' instead.",
-                        localname);
+                D4ParserSax2::dmr_error(parser, "Expected an Attribute element; found '%s' instead.", localname);
             break;
 
         case inside_attribute:
             if (parser->process_attribute(localname, attributes, nb_attributes))
                 break;
-            else if (strcmp(localname, "value") == 0)
-                parser->set_state(inside_attribute_value);
+            else if (strcmp(localname, "Value") == 0)
+                parser->push_state(inside_attribute_value);
             else
-                ddx_fatal_error(parser, "Expected an 'Attribute', 'Alias' or 'value' element; found '%s' instead.",
-                        localname);
+                dmr_error(parser, "Expected an 'Attribute' or 'Value' element; found '%s' instead.", localname);
             break;
 
         case inside_attribute_value:
-            // FIXME
+            // Attribute values are processed by the end element code.
             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);
@@ -673,170 +747,170 @@ void D4ParserSax2::ddx_start_element(void *p, const xmlChar *l, const xmlChar *p
         case inside_enum_def:
             // process an EnumConst element
             if (parser->process_enum_const(localname, attributes, nb_attributes))
-                break;
+                parser->push_state(inside_enum_const);
             else
-                ddx_fatal_error(parser, "Expected an 'EnumConst' element; found '%s' instead.", localname);
+                dmr_error(parser, "Expected an 'EnumConst' element; found '%s' instead.", localname);
             break;
 
         case inside_enum_const:
-            // Nothing to do; this element has no content
-            break;
-
-        case inside_simple_type:
-            if (parser->process_attribute(localname, attributes, nb_attributes))
-                break;
-            else
-                ddx_fatal_error(parser, "Expected an 'Attribute' or 'Alias' element; found '%s' instead.", localname);
+            // No content; nothing to do
             break;
 
-        case inside_array:
-            if (parser->process_attribute(localname, attributes, nb_attributes))
-                break;
-            else if (is_not(localname, "Array") && parser->process_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);
+        case inside_dim_def:
+            // No content; nothing to do
             break;
-
+#if 0
         case inside_dimension:
-            ddx_fatal_error(parser,
-                    "Internal parser error; unexpected state, inside dimension while processing element '%s'.",
-                    localname);
+            // No content.
             break;
-
-        case inside_structure:
-            if (parser->process_attribute(localname, attributes, nb_attributes))
-                break;
-            else if (parser->process_variable(localname, attributes, nb_attributes))
-                break;
-            else
-                D4ParserSax2::ddx_fatal_error(parser,
-                        "Expected an Attribute, Alias or variable element; found '%s' instead.", localname);
+#endif
+        case inside_dim:
+            // No content.
             break;
 
-        case inside_sequence:
-            if (parser->process_attribute(localname, attributes, nb_attributes))
-                break;
-            else if (parser->process_variable(localname, attributes, nb_attributes))
-                break;
-            else
-                D4ParserSax2::ddx_fatal_error(parser,
-                        "Expected an Attribute, Alias or variable element; found '%s' instead.", localname);
+        case inside_map:
+            // No content.
             break;
 
-        case inside_grid:
+        case inside_simple_type:
             if (parser->process_attribute(localname, attributes, nb_attributes))
                 break;
-            else if (strcmp(localname, "Array") == 0)
-                parser->process_variable_helper(dods_array_c, inside_array, attributes, nb_attributes);
-            else if (strcmp(localname, "Map") == 0)
-                parser->process_variable_helper(dods_array_c, inside_map, attributes, nb_attributes);
+            else if (parser->process_dimension(localname, attributes, nb_attributes))
+            	parser->push_state(inside_dim);
+            else if (parser->process_map(localname, attributes, nb_attributes))
+            	parser->push_state(inside_map);
             else
-                D4ParserSax2::ddx_fatal_error(parser,
-                        "Expected an Attribute, Alias or variable element; found '%s' instead.", localname);
+                dmr_error(parser, "Expected an 'Attribute', 'Dim' or 'Map' element; found '%s' instead.", localname);
             break;
 
-        case inside_map:
-            if (parser->process_attribute(localname, attributes, nb_attributes))
+        case inside_constructor:
+            if (parser->process_variable(localname, attributes, nb_attributes))
+                // This will push either inside_simple_type or inside_structure
+                // onto the parser state stack.
                 break;
-            else if (is_not(localname, "Array") && is_not(localname, "Sequence") && is_not(localname, "Grid")
-                    && parser->process_variable(localname, attributes, nb_attributes))
+            else if (parser->process_attribute(localname, attributes, nb_attributes))
                 break;
-            else if (strcmp(localname, "dimension") == 0) {
-                parser->process_dimension(attributes, nb_attributes);
-                // next state: inside_dimension
-            }
+            else if (parser->process_dimension(localname, attributes, nb_attributes))
+                parser->push_state(inside_dim);
+            else if (parser->process_map(localname, attributes, nb_attributes))
+            	parser->push_state(inside_map);
             else
-                ddx_fatal_error(parser,
-                        "Expected an 'Attribute', 'Alias', variable or 'dimension' element; found '%s' instead.",
-                        localname);
+                D4ParserSax2::dmr_error(parser, "Expected an Attribute, Dim, Map or variable element; found '%s' instead.", localname);
             break;
 
         case parser_unknown:
+            // FIXME?
             // *** Never used? If so remove/error
-            parser->set_state(parser_unknown);
+            parser->push_state(parser_unknown);
             break;
 
         case parser_error:
+        case parser_fatal_error:
+            break;
+
+        case parser_end:
+            // FIXME Error?
             break;
     }
 
-    DBGN(cerr << " ... " << states[parser->get_state()] << endl);
+    if (parser->debug()) cerr << "Start element exit state: " << states[parser->get_state()] << endl;
 }
 
-void D4ParserSax2::ddx_end_element(void *p, const xmlChar *l, const xmlChar *prefix, const xmlChar *URI)
+void D4ParserSax2::dmr_end_element(void *p, const xmlChar *l, const xmlChar *prefix, const xmlChar *URI)
 {
     D4ParserSax2 *parser = static_cast<D4ParserSax2*>(p);
     const char *localname = (const char *) l;
 
-    DBG2(cerr << "End element " << localname << " (state "
-            << states[parser->get_state()] << ")" << endl);
+    if (parser->debug()) 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);
+            dmr_fatal_error(parser, "Unexpected state, inside start state while processing element '%s'.", localname);
             break;
 
-        case inside_group:
-            if (strcmp(localname, "Group") == 0)
+        case inside_dataset:
+            if (is_not(localname, "Dataset"))
+                D4ParserSax2::dmr_error(parser, "Expected an end Dataset tag; found '%s' instead.", localname);
+
+            parser->pop_state();
+            if (parser->get_state() != parser_start)
+                dmr_fatal_error(parser, "Unexpected state, expected start state.");
+            else {
                 parser->pop_state();
-            else
-                D4ParserSax2::ddx_fatal_error(parser, "Expected an end Group tag; found '%s' instead.", localname);
+                parser->push_state(parser_end);
+            }
+            break;
+
+        case inside_group: {
+            if (is_not(localname, "Group"))
+                D4ParserSax2::dmr_error(parser, "Expected an end tag for a Group; found '%s' instead.", localname);
+
+            if (!parser->empty_basetype() || parser->empty_group())
+            	D4ParserSax2::dmr_error(parser, "The document did not contain a valid root Group or contained unbalanced tags.");
+
+            parser->pop_group();
+            parser->pop_state();
             break;
+        }
 
         case inside_attribute_container:
-            if (strcmp(localname, "Attribute") == 0) {
-                parser->pop_state();
-                parser->at_stack.pop(); // pop when leaving a container.
-            }
-            else
-                D4ParserSax2::ddx_fatal_error(parser, "Expected an end Attribute tag; found '%s' instead.", localname);
+            if (is_not(localname, "Attribute"))
+                D4ParserSax2::dmr_error(parser, "Expected an end Attribute tag; found '%s' instead.", localname);
+
+            parser->pop_state();
+            parser->pop_attributes();
             break;
 
         case inside_attribute:
-            if (strcmp(localname, "Attribute") == 0)
-                parser->pop_state();
-            else
-                D4ParserSax2::ddx_fatal_error(parser, "Expected an end Attribute tag; found '%s' instead.", localname);
+            if (is_not(localname, "Attribute"))
+                D4ParserSax2::dmr_error(parser, "Expected an end Attribute tag; found '%s' instead.", localname);
+
+            parser->pop_state();
             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.
+        case inside_attribute_value: {
+            if (is_not(localname, "Value"))
+                D4ParserSax2::dmr_error(parser, "Expected an end value tag; found '%s' instead.", localname);
+
+            parser->pop_state();
+
+            // The old code added more values using the name and type as
+            // indexes to find the correct attribute. Use get() for that
+            // now. Or fix this code to keep a pointer to the to attribute...
+            D4Attributes *attrs = parser->top_attributes();
+            D4Attribute *attr = attrs->get(parser->dods_attr_name);
+            if (!attr) {
+                attr = new D4Attribute(parser->dods_attr_name, StringToD4AttributeType(parser->dods_attr_type));
+                attrs->add_attribute_nocopy(attr);
             }
-            else
-                D4ParserSax2::ddx_fatal_error(parser, "Expected an end value tag; found '%s' instead.", localname);
+            attr->add_value(parser->char_data);
 
+            parser->char_data = ""; // Null this after use.
             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);
+                // The old code added more values using the name and type as
+                // indexes to find the correct attribute. Use get() for that
+                // now. Or fix this code to keep a pointer to the to attribute...
+                D4Attributes *attrs = parser->top_attributes();
+                D4Attribute *attr = attrs->get(parser->dods_attr_name);
+                if (!attr) {
+                    attr = new D4Attribute(parser->dods_attr_name, StringToD4AttributeType(parser->dods_attr_type));
+                    attrs->add_attribute_nocopy(attr);
+                }
+                attr->add_value(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)
-                    D4ParserSax2::ddx_fatal_error(parser,
-                            "Expected an OtherXML attribute to end! Instead I found '%s'", localname);
+                if (parser->other_xml_depth == 0) {
+                    D4ParserSax2::dmr_error(parser, "Expected an OtherXML attribute to end! Instead I found '%s'", localname);
+                    break;
+                }
                 parser->other_xml_depth--;
 
                 parser->other_xml.append("</");
@@ -851,108 +925,172 @@ void D4ParserSax2::ddx_end_element(void *p, const xmlChar *l, const xmlChar *pre
         }
 
         case inside_enum_def:
-            if (strcmp(localname, "Enumeration") == 0) {
-                BaseType *btp = parser->bt_stack.top();
-                if (!btp || btp->type() != dods_group_c)
-                    D4ParserSax2::ddx_fatal_error(parser, "Expected a Group to be the current item, while finishing up an %s.", localname);
-                else {
-                    D4Group *g = static_cast<D4Group*>(btp);
-                    g->add_enumeration_nocopy(parser->d_enum_def);
-                    parser->pop_state();
-                }
-            }
+            if (is_not(localname, "Enumeration"))
+                D4ParserSax2::dmr_error(parser, "Expected an end Enumeration tag; found '%s' instead.", localname);
+            if (!parser->top_group())
+                D4ParserSax2::dmr_fatal_error(parser, "Expected a Group to be the current item, while finishing up an Enumeration.");
             else {
-                D4ParserSax2::ddx_fatal_error(parser, "Expected an end Enumeration tag; found '%s' instead.", localname);
+                // copy the pointer; not a deep copy
+                parser->top_group()->enum_defs()->add_enum_nocopy(parser->enum_def());
+                // Set the enum_def to null; next call to enum_def() will
+                // allocate a new object
+                parser->clear_enum_def();
+                parser->pop_state();
             }
             break;
 
         case inside_enum_const:
-            if (strcmp(localname, "EnumConst") == 0)
-                parser->pop_state();
-            else
-                D4ParserSax2::ddx_fatal_error(parser, "Expected an end EnumConst tag; found '%s' instead.", localname);
+            if (is_not(localname, "EnumConst"))
+                D4ParserSax2::dmr_error(parser, "Expected an end EnumConst tag; found '%s' instead.", localname);
+
+            parser->pop_state();
             break;
 
+        case inside_dim_def: {
+            if (is_not(localname, "Dimension"))
+                D4ParserSax2::dmr_error(parser, "Expected an end Dimension tag; found '%s' instead.",  localname);
+
+            if (!parser->top_group())
+                D4ParserSax2::dmr_error(parser, "Expected a Group to be the current item, while finishing up an Dimension.");
+
+            // FIXME Use the Group on the top of the group stack
+            // copy the pointer; not a deep copy
+            parser->top_group()->dims()->add_dim_nocopy(parser->dim_def());
+            //parser->dmr()->root()->dims()->add_dim_nocopy(parser->dim_def());
+            // Set the dim_def to null; next call to dim_def() will
+            // allocate a new object. Calling 'clear' is important because
+            // the cleanup method will free dim_def if it's not null and
+            // we just copied the pointer in the add_dim_nocopy() call
+            // above.
+            parser->clear_dim_def();
+            parser->pop_state();
+            break;
+        }
+
         case inside_simple_type:
             if (is_simple_type(get_type(localname))) {
-                parser->pop_state();
-                BaseType *btp = parser->bt_stack.top();
-                parser->bt_stack.pop();
-                parser->at_stack.pop();
-
-                BaseType *parent = parser->bt_stack.top();
-
-                // NB: This works because we seed the stack with a dummy
-                // structure instance at the start of the parse. When the
-                // parse is complete the variables in that structure will
-                // be transferred to the DDS. Or maybe someday we will really
-                // use a Structure instance in DDS...
-                if (parent->is_vector_type() || parent->is_constructor_type())
-                    parent->add_var(btp);
+                BaseType *btp = parser->top_basetype();
+                parser->pop_basetype();
+                parser->pop_attributes();
+
+                BaseType *parent = 0;
+                if (!parser->empty_basetype())
+                	parent = parser->top_basetype();
+                else if (!parser->empty_group())
+                	parent = parser->top_group();
+                else {
+                	dmr_fatal_error(parser, "Both the Variable and Groups stacks are empty while closing a %s element.", localname);
+                	delete btp;
+                }
+
+                if (parent->type() == dods_array_c)
+                    static_cast<Array*>(parent)->prototype()->add_var_nocopy(btp);
                 else
-                    D4ParserSax2::ddx_fatal_error(parser,
+                    parent->add_var_nocopy(btp);
+            }
+            else
+                D4ParserSax2::dmr_error(parser, "Expected an end tag for a simple type; found '%s' instead.", localname);
+
+            parser->pop_state();
+#if 0
+                // Check that we have a constructor BaseType (Structure, Sequence, or Group)
+               if (parent && parent->is_constructor_type())
+
+                else {
+                    D4ParserSax2::dmr_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());
+                            parser->top_basetype()->type_name().c_str(), parser->top_basetype()->name().c_str());
+                    // since the BaseType* was popped and not copied anywhere,
+                    // it must be deleted.
+                    delete btp;
+                }
             }
             else
-                D4ParserSax2::ddx_fatal_error(parser, "Expected an end tag for a simple type; found '%s' instead.",
-                        localname);
+                D4ParserSax2::dmr_error(parser, "Expected an end tag for a simple type; found '%s' instead.", localname);
+#endif
             break;
 
-        case inside_array:
-            parser->finish_variable(localname, dods_array_c, "Array");
-            break;
+    case inside_dim:
+        if (is_not(localname, "Dim"))
+            D4ParserSax2::dmr_fatal_error(parser, "Expected an end Dim tag; found '%s' instead.", localname);
+
+        parser->pop_state();
+        break;
+
+    case inside_map:
+        if (is_not(localname, "Map"))
+            D4ParserSax2::dmr_fatal_error(parser, "Expected an end Map tag; found '%s' instead.", localname);
 
+        parser->pop_state();
+        break;
+#if 0
+            // a nicer name, but not what we chose
         case inside_dimension:
-            if (strcmp(localname, "dimension") == 0)
-                parser->pop_state();
-            else
-                D4ParserSax2::ddx_fatal_error(parser, "Expected an end dimension tag; found '%s' instead.", localname);
-            break;
+            if (is_not(localname, "dimension"))
+                D4ParserSax2::dmr_fatal_error(parser, "Expected an end Dimension tag; found '%s' instead.", localname);
 
-        case inside_structure:
-            parser->finish_variable(localname, dods_structure_c, "Structure");
+            parser->pop_state();
             break;
+#endif
+        case inside_constructor: {
+            if (strcmp(localname, "Structure") != 0 && strcmp(localname, "Sequence") != 0) {
+                D4ParserSax2::dmr_error(parser, "Expected an end tag for a constructor; found '%s' instead.", localname);
+                return;
+            }
 
-        case inside_sequence:
-            parser->finish_variable(localname, dods_sequence_c, "Sequence");
-            break;
+            BaseType *btp = parser->top_basetype();
+            parser->pop_basetype();
+            parser->pop_attributes();
 
-        case inside_grid:
-            parser->finish_variable(localname, dods_grid_c, "Grid");
-            break;
+            BaseType *parent = 0;
+            if (!parser->empty_basetype())
+            	parent = parser->top_basetype();
+            else if (!parser->empty_group())
+            	parent = parser->top_group();
+            else {
+            	dmr_fatal_error(parser, "Both the Variable and Groups stacks are empty while closing a %s element.", localname);
+            	delete btp;
+            }
 
-        case inside_map:
-            parser->finish_variable(localname, dods_array_c, "Map");
+            // TODO Why doesn't this code mirror the simple_var case and test
+            // for the parent being an array? jhrg 10/13/13
+            parent->add_var_nocopy(btp);
+            parser->pop_state();
             break;
+        }
 
         case parser_unknown:
             parser->pop_state();
             break;
 
         case parser_error:
+        case parser_fatal_error:
+            break;
+
+        case parser_end:
+            // FIXME Error?
             break;
     }
 
-    DBGN(cerr << " ... " << states[parser->get_state()] << endl);
+    if (parser->debug()) cerr << "End element exit state: " << 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 D4ParserSax2::ddx_get_characters(void * p, const xmlChar * ch, int len)
+void D4ParserSax2::dmr_get_characters(void * p, const xmlChar * ch, int len)
 {
     D4ParserSax2 *parser = static_cast<D4ParserSax2*>(p);
 
     switch (parser->get_state()) {
         case inside_attribute_value:
             parser->char_data.append((const char *) (ch), len);
-            DBG2(cerr << "Characters: '" << parser->char_data << "'" << endl);
+            DBG(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);
+            DBG(cerr << "Other XML Characters: '" << parser->other_xml << "'" << endl);
             break;
 
         default:
@@ -964,7 +1102,7 @@ void D4ParserSax2::ddx_get_characters(void * p, const xmlChar * ch, int len)
  only for the OtherXML attribute type to preserve formating of the XML.
  Doing so makes the attribute value far easier to read.
  */
-void D4ParserSax2::ddx_ignoreable_whitespace(void *p, const xmlChar *ch, int len)
+void D4ParserSax2::dmr_ignoreable_whitespace(void *p, const xmlChar *ch, int len)
 {
     D4ParserSax2 *parser = static_cast<D4ParserSax2*>(p);
 
@@ -983,7 +1121,7 @@ void D4ParserSax2::ddx_ignoreable_whitespace(void *p, const xmlChar *ch, int len
  callback also allows CData when the parser is in the 'parser_unknown'
  state since some future DAP element might use it.
  */
-void D4ParserSax2::ddx_get_cdata(void *p, const xmlChar *value, int len)
+void D4ParserSax2::dmr_get_cdata(void *p, const xmlChar *value, int len)
 {
     D4ParserSax2 *parser = static_cast<D4ParserSax2*>(p);
 
@@ -996,7 +1134,7 @@ void D4ParserSax2::ddx_get_cdata(void *p, const xmlChar *value, int len)
             break;
 
         default:
-            D4ParserSax2::ddx_fatal_error(parser, "Found a CData block but none are allowed by DAP.");
+            D4ParserSax2::dmr_error(parser, "Found a CData block but none are allowed by DAP4.");
 
             break;
     }
@@ -1006,7 +1144,7 @@ void D4ParserSax2::ddx_get_cdata(void *p, const xmlChar *value, int len)
 
  @param parser The SAX parser
  @param name The XML entity. */
-xmlEntityPtr D4ParserSax2::ddx_get_entity(void *, const xmlChar * name)
+xmlEntityPtr D4ParserSax2::dmr_get_entity(void *, const xmlChar * name)
 {
     return xmlGetPredefinedEntity(name);
 }
@@ -1021,177 +1159,181 @@ xmlEntityPtr D4ParserSax2::ddx_get_entity(void *, const xmlChar * name)
 
  @param p The SAX parser
  @param msg A printf-style format string. */
-void D4ParserSax2::ddx_fatal_error(void * p, const char *msg, ...)
+void D4ParserSax2::dmr_fatal_error(void * p, const char *msg, ...)
 {
     va_list args;
     D4ParserSax2 *parser = static_cast<D4ParserSax2*>(p);
 
-    parser->set_state(parser_error);
+    parser->push_state(parser_fatal_error);
 
     va_start(args, msg);
     char str[1024];
     vsnprintf(str, 1024, msg, args);
     va_end(args);
 
-    int line = xmlSAX2GetLineNumber(parser->ctxt);
+    int line = xmlSAX2GetLineNumber(parser->context);
 
-    parser->error_msg += "At line " + long_to_string(line) + ": ";
-    parser->error_msg += string(str) + string("\n");
+    if (!parser->error_msg.empty()) parser->error_msg += "\n";
+    parser->error_msg += "At line " + long_to_string(line) + ": " + string(str);
 }
 
+void D4ParserSax2::dmr_error(void *p, const char *msg, ...)
+{
+    va_list args;
+    D4ParserSax2 *parser = static_cast<D4ParserSax2*>(p);
+
+    parser->push_state(parser_error);
+
+    va_start(args, msg);
+    char str[1024];
+    vsnprintf(str, 1024, msg, args);
+    va_end(args);
+
+    int line = xmlSAX2GetLineNumber(parser->context);
+
+    if (!parser->error_msg.empty()) parser->error_msg += "\n";
+    parser->error_msg += "At line " + long_to_string(line) + ": " + string(str);
+}
 //@}
 
-void D4ParserSax2::cleanup_parse(xmlParserCtxtPtr & context) const
+/** Clean up after a parse operation. If the parser encountered an error,
+ * throw either an Error or InternalErr object.
+ */
+void D4ParserSax2::cleanup_parse()
 {
-    if (!context->wellFormed) {
-        context->sax = NULL;
-        xmlFreeParserCtxt(context);
-        throw D4ParseError(string("\nThe DDX is not a well formed XML document.\n") + error_msg);
-    }
+    bool wellFormed = context->wellFormed;
+    bool valid = context->valid;
 
-    if (!context->valid) {
-        context->sax = NULL;
-        xmlFreeParserCtxt(context);
-        throw D4ParseError(string("\nThe DDX is not a valid document.\n") + error_msg);
-    }
+    context->sax = NULL;
+    xmlFreeParserCtxt(context);
+
+    delete d_enum_def;
+    d_enum_def = 0;
+
+    delete d_dim_def;
+    d_dim_def = 0;
 
-    if (get_state() == parser_error) {
-        context->sax = NULL;
-        xmlFreeParserCtxt(context);
-        throw D4ParseError(string("\nError parsing DMR response.\n") + error_msg);
+    // If there's an error, there may still be items on the stack at the
+    // end of the parse.
+    while (!btp_stack.empty()) {
+        delete top_basetype();
+        pop_basetype();
     }
 
-    context->sax = NULL;
-    xmlFreeParserCtxt(context);
+    if (!wellFormed)
+        throw Error("The DMR was not well formed. " + error_msg);
+    else if (!valid)
+        throw Error("The DMR was not valid." + error_msg);
+    else if (get_state() == parser_error)
+        throw Error(error_msg);
+    else if (get_state() == parser_fatal_error)
+        throw InternalErr(error_msg);
 }
 
 /**
- * @brief Read the DDX from a stream instead of a file.
- *
- * This method reads and parses the DDX from a stream. When/if it encounters
- * the <blob> element is records the value of the  CID attribute and returns
- * it using the cid value-result parameter. When the boundary marker is
- * found, the parser will read that and return (if it is found before the
- * DDX is completely parsed).
+ * Read the DMR from a stream.
  *
  * @param f The input stream
- * @param dest_dds Value-result parameter. Pass a DDS in and the inforamtion
- * in the DDX will be added to it.
- * @param cid Value-result parameter. When/if read, the value of the <blob>
- * element's @cid attribute will be returned here.
- * @param boundary Value of the M-MIME boundary separator; default is ""
- * @see DDXParserDAP4::intern(). */
-void D4ParserSax2::intern(istream &f, DDS *dest_dds)
+ * @param dest_dmr Value-result parameter. Pass a pointer to a DMR in and
+ * the information in the DMR will be added to it.
+ * @param boundary If not empty, use this as the boundary tag in a MPM document
+ * that marks the end of the part hat holds the DMR. Stop reading when the
+ * boundary is found.
+ * @param debug If true, ouput helpful debugging messages, False by default.
+ *
+ * @exception Error Thrown if the XML document could not be read or parsed.
+ * @exception InternalErr Thrown if an internal error is found.
+ */
+void D4ParserSax2::intern(istream &f, DMR *dest_dmr, bool debug)
 {
+    d_debug = debug;
+
     // Code example from libxml2 docs re: read from a stream.
 
     if (!f.good())
-        throw InternalErr(__FILE__, __LINE__, "Input stream not open or read error");
+        throw Error("Input stream not open or read error");
+    if (!dest_dmr)
+        throw InternalErr(__FILE__, __LINE__, "DMR object is null");
+
+    d_dmr = dest_dmr; // dump values here
 
     const int size = 1024;
     char chars[size];
+    int line = 1;
 
     f.getline(chars, size);
     int res = f.gcount();
-    if (res > 0) {
-
-        DBG(cerr << "line: (" << res << "): " << chars << endl);
-        xmlParserCtxtPtr context = xmlCreatePushParserCtxt(NULL, NULL, chars, res - 1, "stream");
-
-        ctxt = context; // need ctxt for error messages
-        dds = dest_dds; // dump values here
-        d_factory = dynamic_cast<D4BaseTypeFactory*>(dds->get_factory());
-        if (!d_factory)
-            throw InternalErr(__FILE__, __LINE__, "Invalid factory class");
-
-        xmlSAXHandler ddx_sax_parser;
-        memset(&ddx_sax_parser, 0, sizeof(xmlSAXHandler));
-
-        ddx_sax_parser.getEntity = &D4ParserSax2::ddx_get_entity;
-        ddx_sax_parser.startDocument = &D4ParserSax2::ddx_start_document;
-        ddx_sax_parser.endDocument = &D4ParserSax2::ddx_end_document;
-        ddx_sax_parser.characters = &D4ParserSax2::ddx_get_characters;
-        ddx_sax_parser.ignorableWhitespace = &D4ParserSax2::ddx_ignoreable_whitespace;
-        ddx_sax_parser.cdataBlock = &D4ParserSax2::ddx_get_cdata;
-        ddx_sax_parser.warning = &D4ParserSax2::ddx_fatal_error;
-        ddx_sax_parser.error = &D4ParserSax2::ddx_fatal_error;
-        ddx_sax_parser.fatalError = &D4ParserSax2::ddx_fatal_error;
-        ddx_sax_parser.initialized = XML_SAX2_MAGIC;
-        ddx_sax_parser.startElementNs = &D4ParserSax2::ddx_start_element;
-        ddx_sax_parser.endElementNs = &D4ParserSax2::ddx_end_element;
-
-        context->sax = &ddx_sax_parser;
-        context->userData = this;
-        context->validate = true;
+    if (res == 0) throw Error("No input found while parsing the DMR.");
 
-        f.getline(chars, size);
-        while ((f.gcount() > 0)) {
-            DBG(cerr << "line: (" << f.gcount() << "): " << chars << endl);
-            xmlParseChunk(ctxt, chars, f.gcount() - 1, 0);
-            f.getline(chars, size);
-        }
-        // This call ends the parse: The fourth argument of xmlParseChunk is
-        // the bool 'terminate.'
-        xmlParseChunk(ctxt, chars, 0, 1);
+    if (debug) cerr << "line: (" << line++ << "): " << chars << endl;
 
-        cleanup_parse(context);
+    context = xmlCreatePushParserCtxt(&ddx_sax_parser, this, chars, res - 1, "stream");
+    context->validate = true;
+    push_state(parser_start);
+
+    f.getline(chars, size);
+    while ((f.gcount() > 0) && (get_state() != parser_end)) {
+        if (debug) cerr << "line: (" << line++ << "): " << chars << endl;
+        xmlParseChunk(context, chars, f.gcount() - 1, 0);
+        f.getline(chars, size);
     }
+
+    // This call ends the parse.
+    xmlParseChunk(context, chars, 0, 1/*terminate*/);
+
+    // This checks that the state on the parser stack is parser_end and throws
+    // an exception if it's not (i.e., the loop exited with gcount() == 0).
+    cleanup_parse();
 }
 
-/** 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 D4ParseError Thrown if the XML document could not be
- read or parsed. */
-void D4ParserSax2::intern(const string &document, DDS *dest_dds)
+/** Parse a DMR document stored in a string.
+ *
+ * @param document Read the DMR from this string.
+ * @param dest_dmr Value/result parameter; dumps the information to this DMR
+ * instance.
+ * @param debug If true, ouput helpful debugging messages, False by default
+ *
+ * @exception Error Thrown if the XML document could not be read or parsed.
+ * @exception InternalErr Thrown if an internal error is found.
+ */
+void D4ParserSax2::intern(const string &document, DMR *dest_dmr, bool debug)
 {
-    istringstream iss(document);
-    intern(iss, dest_dds);
-#if 0
-    // Create the context pointer explicitly so that we can store a pointer
-    // to it in the DDXParserDAP4 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 D4ParseError(string("Could not initialize the parser with the file: '") + document + string("'."));
-
-    dds = dest_dds; // dump values here
-    ctxt = context; // need ctxt for error messages
-
-    xmlSAXHandler ddx_sax_parser;
-    memset(&ddx_sax_parser, 0, sizeof(xmlSAXHandler));
-
-    ddx_sax_parser.getEntity = &D4ParserSax2::ddx_get_entity;
-    ddx_sax_parser.startDocument = &D4ParserSax2::ddx_start_document;
-    ddx_sax_parser.endDocument = &D4ParserSax2::ddx_end_document;
-    ddx_sax_parser.characters = &D4ParserSax2::ddx_get_characters;
-    ddx_sax_parser.ignorableWhitespace = &D4ParserSax2::ddx_ignoreable_whitespace;
-    ddx_sax_parser.cdataBlock = &D4ParserSax2::ddx_get_cdata;
-    ddx_sax_parser.warning = &D4ParserSax2::ddx_fatal_error;
-    ddx_sax_parser.error = &D4ParserSax2::ddx_fatal_error;
-    ddx_sax_parser.fatalError = &D4ParserSax2::ddx_fatal_error;
-    ddx_sax_parser.initialized = XML_SAX2_MAGIC;
-    ddx_sax_parser.startElementNs = &D4ParserSax2::ddx_start_element;
-    ddx_sax_parser.endElementNs = &D4ParserSax2::ddx_end_element;
-
-    context->sax = &ddx_sax_parser;
-    context->userData = this;
-    context->validate = false;
-
-    xmlParseDocument(context);
-
-    cleanup_parse(context);
-#endif
+    intern(document.c_str(), document.length(), dest_dmr, debug);
+}
+
+/** Parse a DMR document stored in a char *buffer.
+ *
+ * @param document Read the DMR from this string.
+ * @param dest_dmr Value/result parameter; dumps the information to this DMR
+ * instance.
+ * @param debug If true, ouput helpful debugging messages, False by default
+ *
+ * @exception Error Thrown if the XML document could not be read or parsed.
+ * @exception InternalErr Thrown if an internal error is found.
+ */
+void D4ParserSax2::intern(const char *buffer, int size, DMR *dest_dmr, bool debug)
+{
+    if (!(size > 0)) return;
+
+    d_debug = debug;
+
+    // Code example from libxml2 docs re: read from a stream.
+
+    if (!dest_dmr) throw InternalErr(__FILE__, __LINE__, "DMR object is null");
+    d_dmr = dest_dmr; // dump values in dest_dmr
+
+    push_state(parser_start);
+    context = xmlCreatePushParserCtxt(&ddx_sax_parser, this, buffer, size, "stream");
+    context->validate = true;
+    //push_state(parser_start);
+    //xmlParseChunk(context, buffer, size, 0);
+
+    // This call ends the parse.
+    xmlParseChunk(context, buffer, 0, 1/*terminate*/);
+
+    // This checks that the state on the parser stack is parser_end and throws
+    // an exception if it's not (i.e., the loop exited with gcount() == 0).
+    cleanup_parse();
 }
 
 } // namespace libdap
diff --git a/D4ParserSax2.h b/D4ParserSax2.h
index 716911d..2f123ce 100644
--- a/D4ParserSax2.h
+++ b/D4ParserSax2.h
@@ -26,6 +26,10 @@
 #ifndef d4_parser_sax2_h
 #define d4_parser_sax2_h
 
+#define ATTR 1
+
+#include <string.h>
+
 #include <string>
 #include <iostream>
 #include <map>
@@ -33,16 +37,19 @@
 
 #include <libxml/parserInternals.h>
 
-#include "DDS.h"
-#include "BaseType.h"
-//#include "D4EnumDef.h"
-#include "D4BaseTypeFactory.h"
-
-#include "D4ParseError.h"
+#define CRLF "\r\n"
 
 namespace libdap
 {
 
+class DMR;
+class BaseType;
+class D4BaseTypeFactory;
+class D4Group;
+class D4Attributes;
+class D4EnumDef;
+class D4Dimension;
+
 /** Parse the XML text which encodes the network/persistent representation of
     the DMR object. In the current implementation, the DMR is held by an
     instance of the class DDS which in turn holds variables which include
@@ -58,14 +65,14 @@ namespace libdap
     construction of an DMR object ends even though the SAX parser still
     calls the various callback functions. The parser treats warnings,
     errors and fatal_errors the same way; when any are found parsing
-    stops. The intern method throws an D4ParseError exception if an
+    stops. The intern method throws an Error of InternalErr 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 */
+    @see DMR */
 class D4ParserSax2
 {
 private:
@@ -74,11 +81,12 @@ private:
     enum ParseState {
         parser_start,
 
+        inside_dataset,
+
         // inside_group is the state just after parsing the start of a Group
         // element.
         inside_group,
 
-        // @TODO Parse attributes once the variables are working.
         inside_attribute_container,
         inside_attribute,
         inside_attribute_value,
@@ -87,33 +95,77 @@ private:
         inside_enum_def,
         inside_enum_const,
 
+        inside_dim_def,
+
         // This covers Byte, ..., Url, Opaque
         inside_simple_type,
 
-        inside_array,
-        inside_dimension,
-
-        inside_grid,
+        // inside_array,
+        inside_dim,
         inside_map,
 
-        inside_structure,
-        inside_sequence,
+        inside_constructor,
+
+        // inside_sequence, Removed from merged code jhrg 5/2/14
 
         parser_unknown,
-        parser_error
+        parser_error,
+        parser_fatal_error,
+
+        parser_end
     };
 
-    D4BaseTypeFactory *d_factory;
+    xmlSAXHandler ddx_sax_parser;
+
+    // The results of the parse operation are stored in these fields.
+    // This is passed into the parser using the intern() methods.
+    DMR *d_dmr;   // dump DMR here
+    DMR *dmr() const { return d_dmr; }
 
     // These stacks hold the state of the parse as it progresses.
     stack<ParseState> s; // Current parse state
-    stack<BaseType*> bt_stack; // current variable(s)/groups(s)
-    stack<AttrTable*> at_stack; // current attribute table
+    void push_state(D4ParserSax2::ParseState state) { s.push(state); }
+    D4ParserSax2::ParseState get_state() const { return s.top(); }
+    void pop_state() { s.pop(); }
+    bool empty_state() const { return s.empty(); }
+
+    stack<BaseType*> btp_stack; // current variable(s)
+    void push_basetype(BaseType *btp) { btp_stack.push(btp); }
+    BaseType *top_basetype() const { return btp_stack.top(); }
+    void pop_basetype() { btp_stack.pop(); }
+    bool empty_basetype() const { return btp_stack.empty(); }
+
+    stack<D4Group*> grp_stack; // current groups(s)
+    void push_group(D4Group *grp) { grp_stack.push(grp); }
+    D4Group *top_group() const { return grp_stack.top(); }
+    void pop_group() { grp_stack.pop(); }
+    bool empty_group() const { return grp_stack.empty(); }
+
+    stack<D4Attributes*> d_attrs_stack; // DAP4 Attributes
+    void push_attributes(D4Attributes *attr) { d_attrs_stack.push(attr); }
+    D4Attributes *top_attributes() const { return d_attrs_stack.top(); }
+    void pop_attributes() { d_attrs_stack.pop(); }
+    bool empty_attributes() const { return d_attrs_stack.empty(); }
 
-#if 0
-    // If an enumeration being defined, hold it here until its complete
     D4EnumDef *d_enum_def;
+    D4EnumDef *enum_def();
+#if 0
+    {
+        if (!d_enum_def) d_enum_def = new D4EnumDef;
+        return d_enum_def;
+    }
+#endif
+    void clear_enum_def() { d_enum_def = 0; }
+
+    D4Dimension *d_dim_def;
+    D4Dimension *dim_def();
+#if 0
+    {
+        if (!d_dim_def) d_dim_def = new D4Dimension;
+        return d_dim_def;
+    }
 #endif
+    void clear_dim_def() { d_dim_def = 0; }
 
     // Accumulate stuff inside an 'OtherXML' DAP attribute here
     string other_xml;
@@ -125,10 +177,7 @@ private:
 
     // 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 DMR here
+    xmlParserCtxtPtr context; // used for error message line numbers
 
     // These hold temporary values read during the parse.
     string dods_attr_name; // DAP4 attributes, not XML attributes
@@ -136,6 +185,9 @@ private:
     string char_data;  // char data in value elements; null after use
     string root_ns;     // What is the namespace of the root node (Group)
 
+    bool d_debug;
+    bool debug() const { return d_debug; }
+
     class XMLAttribute {
         public:
         string prefix;
@@ -172,26 +224,13 @@ private:
     typedef map<string, XMLAttribute> XMLAttrMap;
     XMLAttrMap xml_attrs; // dump XML attributes here
 
-    XMLAttrMap::iterator xml_attr_begin() {
-        return xml_attrs.begin();
-    }
+    XMLAttrMap::iterator xml_attr_begin() { return xml_attrs.begin(); }
 
-    XMLAttrMap::iterator xml_attr_end() {
-        return xml_attrs.end();
-    }
+    XMLAttrMap::iterator xml_attr_end() {  return xml_attrs.end(); }
 
     map<string, string> namespace_table;
 
-    // These are kind of silly...
-    void set_state(D4ParserSax2::ParseState state);
-    D4ParserSax2::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;
+    void cleanup_parse();
 
     /** @name Parser Actions
 
@@ -203,19 +242,17 @@ private:
     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_helper(const xmlChar **attrs, int nb_attrs);
-
     void process_variable_helper(Type t, ParseState s, const xmlChar **attrs, int nb_attributes);
 
     void process_enum_const_helper(const xmlChar **attrs, int nb_attributes);
     void process_enum_def_helper(const xmlChar **attrs, int nb_attributes);
 
-    void process_dimension(const xmlChar **attrs, int nb_attrs);
-
+    bool process_dimension(const char *name, const xmlChar **attrs, int nb_attrs);
+    bool process_dimension_def(const char *name, const xmlChar **attrs, int nb_attrs);
+    bool process_map(const char *name, const xmlChar **attrs, int nb_attributes);
     bool process_attribute(const char *name, const xmlChar **attrs, int nb_attributes);
     bool process_variable(const char *name, const xmlChar **attrs, int nb_attributes);
-
+    bool process_group(const char *name, const xmlChar **attrs, int nb_attributes);
     bool process_enum_def(const char *name, const xmlChar **attrs, int nb_attributes);
     bool process_enum_const(const char *name, const xmlChar **attrs, int nb_attributes);
 
@@ -225,35 +262,52 @@ private:
     friend class D4ParserSax2Test;
 
 public:
-    // Read the factory class used to build BaseTypes from the DDS passed
-    // into the intern() method.
-    D4ParserSax2() : d_factory(0),
+    D4ParserSax2() :
+        d_dmr(0), d_enum_def(0), d_dim_def(0),
         other_xml(""), other_xml_depth(0), unknown_depth(0),
-        error_msg(""), ctxt(0), dds(0),
+        error_msg(""), context(0),
         dods_attr_name(""), dods_attr_type(""),
-        char_data(""), root_ns("")
-    {}
+        char_data(""), root_ns(""), d_debug(false)
+    {
+        //xmlSAXHandler ddx_sax_parser;
+        memset(&ddx_sax_parser, 0, sizeof(xmlSAXHandler));
+
+        ddx_sax_parser.getEntity = &D4ParserSax2::dmr_get_entity;
+        ddx_sax_parser.startDocument = &D4ParserSax2::dmr_start_document;
+        ddx_sax_parser.endDocument = &D4ParserSax2::dmr_end_document;
+        ddx_sax_parser.characters = &D4ParserSax2::dmr_get_characters;
+        ddx_sax_parser.ignorableWhitespace = &D4ParserSax2::dmr_ignoreable_whitespace;
+        ddx_sax_parser.cdataBlock = &D4ParserSax2::dmr_get_cdata;
+        ddx_sax_parser.warning = &D4ParserSax2::dmr_error;
+        ddx_sax_parser.error = &D4ParserSax2::dmr_error;
+        ddx_sax_parser.fatalError = &D4ParserSax2::dmr_fatal_error;
+        ddx_sax_parser.initialized = XML_SAX2_MAGIC;
+        ddx_sax_parser.startElementNs = &D4ParserSax2::dmr_start_element;
+        ddx_sax_parser.endElementNs = &D4ParserSax2::dmr_end_element;
+    }
 
-    void intern(const string &document, DDS *dest_dds);
-    void intern(istream &in, DDS *dest_dds);
+    void intern(istream &f, DMR *dest_dmr, bool debug = false);
+    void intern(const string &document, DMR *dest_dmr, bool debug = false);
+    void intern(const char *buffer, int size, DMR *dest_dmr, bool debug = false);
 
-    static void ddx_start_document(void *parser);
-    static void ddx_end_document(void *parser);
+    static void dmr_start_document(void *parser);
+    static void dmr_end_document(void *parser);
 
-    static void ddx_start_element(void *parser,
+    static void dmr_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_end_element(void *parser, const xmlChar *localname,
+    static void dmr_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,
+    static void dmr_get_characters(void *parser, const xmlChar *ch, int len);
+    static void dmr_ignoreable_whitespace(void *parser,
             const xmlChar * ch, int len);
-    static void ddx_get_cdata(void *parser, const xmlChar *value, int len);
+    static void dmr_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, ...);
+    static xmlEntityPtr dmr_get_entity(void *parser, const xmlChar *name);
+    static void dmr_fatal_error(void *parser, const char *msg, ...);
+    static void dmr_error(void *parser, const char *msg, ...);
 };
 
 } // namespace libdap
diff --git a/D4RValue.cc b/D4RValue.cc
new file mode 100644
index 0000000..629e7e4
--- /dev/null
+++ b/D4RValue.cc
@@ -0,0 +1,218 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2014 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include <cassert>
+#include <iostream>
+
+#include "BaseType.h"
+#include "Array.h"
+#include "Byte.h"
+#include "Int8.h"
+#include "UInt16.h"
+#include "Int16.h"
+#include "UInt32.h"
+#include "Int32.h"
+#include "UInt64.h"
+#include "Int64.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+
+#include "D4RValue.h"
+#include "InternalErr.h"
+
+#include "dods-datatypes.h"
+#include "dods-limits.h"
+#include "util.h"
+
+using namespace std;
+
+namespace libdap {
+
+D4RValueList::~D4RValueList()
+{
+	for (std::vector<D4RValue *>::iterator i = d_rvalues.begin(), e = d_rvalues.end(); i != e; ++i)
+		delete *i;
+}
+
+template<typename T, class DAP_TYPE>
+static BaseType *
+build_constant_array(vector<T> &values, DAP_TYPE &dt)
+{
+    Array *array = new Array("", &dt);
+    array->append_dim(values.size());
+
+    // TODO Make set_value_nocopy() methods so that values' pointers can be copied
+    // instead of allocating memory twice. jhrg 7/5/13
+
+    array->set_value(values, values.size());
+
+    array->set_read_p(true);
+
+    static unsigned long counter = 1;
+    array->set_name(string("g") + long_to_string(counter++));
+
+    return array;
+}
+
+D4RValue::D4RValue(unsigned long long ull) : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
+{
+	UInt64 *ui = new UInt64("constant");
+	ui->set_value(ull);
+	d_constant = ui;
+}
+
+D4RValue::D4RValue(long long ll) : d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Int64 *i = new Int64("constant");
+	i->set_value(ll);
+	d_constant = i;
+}
+
+D4RValue::D4RValue(double r) : d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Float64 *f = new Float64("constant");
+	f->set_value(r);
+	d_constant = f;
+}
+
+D4RValue::D4RValue(std::string cpps) : d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Str *s = new Str("constant");
+	s->set_value(remove_quotes(cpps));
+	d_constant = s;
+}
+
+D4RValue::D4RValue(std::vector<dods_byte> &byte_args)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Byte b("");
+	d_constant = build_constant_array(byte_args, b);
+}
+
+D4RValue::D4RValue(std::vector<dods_int8> &byte_int8)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Int8 b("");
+	d_constant = build_constant_array(byte_int8, b);
+}
+
+D4RValue::D4RValue(std::vector<dods_uint16> &byte_uint16)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	UInt16 b("");
+	d_constant = build_constant_array(byte_uint16, b);
+}
+
+D4RValue::D4RValue(std::vector<dods_int16> &byte_int16)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Int16 b("");
+	d_constant = build_constant_array(byte_int16, b);
+}
+
+D4RValue::D4RValue(std::vector<dods_uint32> &byte_uint32)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	UInt32 b("");
+	d_constant = build_constant_array(byte_uint32, b);
+}
+
+D4RValue::D4RValue(std::vector<dods_int32> &byte_int32)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Int32 b("");
+	d_constant = build_constant_array(byte_int32, b);
+}
+
+D4RValue::D4RValue(std::vector<dods_uint64> &byte_uint64)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	UInt64 b("");
+	d_constant = build_constant_array(byte_uint64, b);
+}
+
+D4RValue::D4RValue(std::vector<dods_int64> &byte_int64)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Int64 b("");
+	d_constant = build_constant_array(byte_int64, b);
+}
+
+D4RValue::D4RValue(std::vector<dods_float32> &byte_float32)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Float32 b("");
+	d_constant = build_constant_array(byte_float32, b);
+}
+
+D4RValue::D4RValue(std::vector<dods_float64> &byte_float64)
+	: d_variable(0), d_func(0), d_args(0),  d_constant(0), d_value_kind(constant)
+{
+	Float64 b("");
+	d_constant = build_constant_array(byte_float64, b);
+}
+
+D4RValue::~D4RValue() {
+	// d_variable and d_func are weak pointers; don't delete.
+	delete d_args;
+	delete d_constant;
+}
+
+/** Return the BaseType * for a given RValue.
+ *
+ * @note Unlike the DAP2 functions, we have an easier-to-follow memory model for
+ * function values. The values (BaseType*) returned by this method will be packaged
+ * up in a RValueList and deleted when that list is deleted. Constant values and
+ * function result values will be deleted at that time; variables will not. Thus
+ * Server Functions should always allocate storage for their return values.
+ *
+ * @param dmr The DMR to pass to a function.
+ * @return A BaseType* that holds the value.
+ */
+BaseType *
+D4RValue::value(DMR &dmr)
+{
+	switch (d_value_kind) {
+	case basetype:
+		d_variable->read();
+		d_variable->set_read_p(true);
+		return d_variable;
+
+	case function:
+		return (*d_func)(d_args, dmr);
+
+	case constant:
+		return d_constant;
+
+	default:
+		throw InternalErr(__FILE__, __LINE__, "Unknown rvalue type.");
+	};
+}
+
+} // namespace libdap
+
diff --git a/D4RValue.h b/D4RValue.h
new file mode 100644
index 0000000..845c398
--- /dev/null
+++ b/D4RValue.h
@@ -0,0 +1,122 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2014 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _D4RValue_h
+#define _D4RValue_h
+
+#include <vector>
+
+#include <dods-datatypes.h>
+#include <D4Function.h>
+
+namespace libdap
+{
+
+class BaseType;
+class D4Constant;
+class D4RValue;
+
+class D4RValueList
+{
+private:
+	std::vector<D4RValue *> d_rvalues;
+
+public:
+	typedef std::vector<D4RValue *>::iterator iter;
+
+	D4RValueList() { }
+	D4RValueList(D4RValue *rv) { add_rvalue(rv); }
+
+	~D4RValueList();
+
+	void add_rvalue(D4RValue *rv) {
+		d_rvalues.push_back(rv);
+	}
+
+	D4RValue *get_rvalue(unsigned int i) {
+		return d_rvalues.at(i);
+	}
+
+	iter begin() { return d_rvalues.begin(); }
+	iter end() { return d_rvalues.end(); }
+
+	unsigned int size() const { return d_rvalues.size(); }
+
+};
+
+/** Holds the RValues for the D4 function parser
+ *
+ */
+class D4RValue
+{
+private:
+    BaseType *d_variable;	// This is a weak pointer
+
+    D4Function d_func;  	// (weak) Pointer to a function returning BaseType *
+    D4RValueList *d_args;  	// Strong pointer to arguments to the function; delete
+
+    BaseType *d_constant;	// Strong pointer; delete
+
+    enum value_kind {
+    	unknown,
+    	basetype,
+    	function,
+    	constant
+    };
+
+    value_kind d_value_kind;
+
+    friend class D4RValueList;
+
+public:
+    D4RValue() : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(unknown) { }
+
+    D4RValue(BaseType *btp)  : d_variable(btp), d_func(0), d_args(0), d_constant(0), d_value_kind(basetype) { }
+    D4RValue(D4Function f, D4RValueList *args)  : d_variable(0), d_func(f), d_args(args), d_constant(0), d_value_kind(function) { }
+
+    D4RValue(unsigned long long ui);
+    D4RValue(long long i);
+    D4RValue(double r);
+    D4RValue(std::string s);
+    D4RValue(std::vector<dods_byte> &byte_args);
+    D4RValue(std::vector<dods_int8> &byte_int8);
+    D4RValue(std::vector<dods_uint16> &byte_uint16);
+    D4RValue(std::vector<dods_int16> &byte_int16);
+    D4RValue(std::vector<dods_uint32> &byte_uint32);
+    D4RValue(std::vector<dods_int32> &byte_int32);
+    D4RValue(std::vector<dods_uint64> &byte_uint64);
+    D4RValue(std::vector<dods_int64> &byte_int64);
+    D4RValue(std::vector<dods_float32> &byte_float32);
+    D4RValue(std::vector<dods_float64> &byte_float64);
+
+    virtual ~D4RValue();
+
+    // This is the call that will be used to return the value of a function.
+    // jhrg 3/10/14
+    BaseType *value(DMR &dmr);
+};
+
+} // namespace libdap
+#endif // _RValue_h
diff --git a/D4Sequence.cc b/D4Sequence.cc
new file mode 100644
index 0000000..c18174c
--- /dev/null
+++ b/D4Sequence.cc
@@ -0,0 +1,525 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 <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 "D4Sequence.h"
+
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
+#include "debug.h"
+#include "Error.h"
+#include "InternalErr.h"
+#include "util.h"
+#include "escaping.h"
+
+using namespace std;
+
+namespace libdap {
+
+#if 0
+// Keep this stuff around in case we decide to switch back to sentinels
+
+static const unsigned char end_of_sequence = 0xA5;// binary pattern 1010 0101
+static const unsigned char start_of_instance = 0x5A;// binary pattern 0101 1010
+
+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);
+}
+#endif
+
+// Private member functions
+
+// A reminder of these type defs
+//
+// typedef vector<BaseType *> D4SeqRow;
+// typedef vector<D4SeqRow *> D4SeqValues;
+// D4SeqValues d_values;
+
+void D4Sequence::m_duplicate(const D4Sequence &s)
+{
+    d_length = s.d_length;
+#if INDEX_SUBSETTING
+    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;
+#endif
+    // Deep copy for the values
+    for (D4SeqValues::const_iterator i = s.d_values.begin(), e = s.d_values.end(); i != e; ++i) {
+        D4SeqRow &row = **i;
+        D4SeqRow *dest = new D4SeqRow;
+        for (D4SeqRow::const_iterator j = row.begin(), e = row.end(); j != e; ++j) {
+            // *j is a BaseType*
+            dest->push_back((*j)->ptr_duplicate());
+        }
+
+        d_values.push_back(dest);
+    }
+}
+
+// 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. */
+D4Sequence::D4Sequence(const string &n) :
+        Constructor(n, dods_sequence_c, true /* is dap4 */), d_length(0) // , d_starting_row_number(-1), d_row_stride(1), d_ending_row_number(-1)
+{
+}
+
+/** 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. */
+D4Sequence::D4Sequence(const string &n, const string &d) :
+        Constructor(n, d, dods_sequence_c, true /* is dap4 */), d_length(0) //, d_starting_row_number(-1), d_row_stride(1), d_ending_row_number(-1)
+{
+}
+
+/** @brief The Sequence copy constructor. */
+D4Sequence::D4Sequence(const D4Sequence &rhs) :
+        Constructor(rhs)
+{
+    m_duplicate(rhs);
+}
+
+BaseType *
+D4Sequence::ptr_duplicate()
+{
+    return new D4Sequence(*this);
+}
+
+static inline void delete_bt(BaseType *bt_ptr)
+{
+    delete bt_ptr;
+}
+
+static inline void delete_rows(D4SeqRow *bt_row_ptr)
+{
+    for_each(bt_row_ptr->begin(), bt_row_ptr->end(), delete_bt);
+
+    delete bt_row_ptr;
+}
+
+D4Sequence::~D4Sequence()
+{
+    for_each(d_values.begin(), d_values.end(), delete_rows);
+}
+
+D4Sequence &
+D4Sequence::operator=(const D4Sequence &rhs)
+{
+    if (this == &rhs) return *this;
+
+    dynamic_cast<Constructor &>(*this) = rhs; // run Constructor=
+
+    m_duplicate(rhs);
+
+    return *this;
+}
+
+/**
+ * @brief Read the next instance of the sequence
+ * While the rest of the variables' read() methods are assumed to return the entire
+ * variable in one call (modulo enhancements of the library to support streaming
+ * large variables), this class assumes that the underlying data store is return
+ * data from a table of unknown size. Thus, D4Sequence::read() is assumed to return
+ * one instance (or element or row) of the sequence per call and return true when the
+ * EOF (end of the sequence) is reached.
+ *
+ * For each call to read, the values for each of the sequence's members
+ * are expected to have been loaded into the member's BaseType variables; this
+ * method will copy them out and store then in the D4Sequence's internal storage.
+ * This method always returns the next instance that satisfies the CE when 'filter'
+ * is true.
+ *
+ * @note this method is called by D4Sequence::serialize() and it will evaluate the
+ * CE for each set of values read.
+ *
+ * @param dmr
+ * @param eval
+ * @param filter
+ * @return False when read() indicates that the EOF was found, true otherwise.
+ */
+bool D4Sequence::read_next_instance(/*DMR &dmr, ConstraintEvaluator &eval,*/bool filter)
+{
+    bool eof = false;
+    bool done = false;
+
+    do {
+        eof = read();
+        // Advance the row number if ce_eval is false (we're not supposed to
+        // evaluate the selection) or both filter and the selection are
+        // true.
+        // FIXME CE's not supported for DAP4 yet. jhrg 10/11/13
+        filter = false;
+        if (!eof && (!filter /*|| eval.eval_selection(dmr, dataset()*/)) {
+            d_length++;
+            done = true;
+        }
+    } while (!eof && !done);
+
+    DBG(cerr << "D4Sequence::read_next_instance eof: " << eof << endl);
+    return !eof;
+}
+
+#if 0
+// Used the version in Constructor, which throws an exception because we should
+// not compute these for constructor types. In the case of Sequence, it requires
+// that the values all get read.
+/**
+ * @brief Compute the checksum for a D4Sequence
+ *
+ * @param checksum
+ * @param dmr
+ * @param eval
+ */
+void
+D4Sequence::compute_checksum(Crc32 &checksum, DMR &dmr, ConstraintEvaluator &eval)
+{
+    // Read the data values, then serialize.
+    while (read_next_instance(dmr, eval, true)) {
+        for (Vars_iter i = d_vars.begin(), e = d_vars.end(); i != e; i++) {
+            if ((*i)->send_p()) {
+                (*i)->compute_checksum(checksum);
+            }
+        }
+    }
+}
+#endif
+
+void D4Sequence::intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator &eval*/)
+{
+    // Read the data values, then serialize.
+    while (read_next_instance(/*dmr, eval,*/true /*filter*/)) {
+        D4SeqRow *row = new D4SeqRow;
+        for (Vars_iter i = d_vars.begin(), e = d_vars.end(); i != e; i++) {
+            if ((*i)->send_p()) {
+                // store the variable's value.
+                row->push_back((*i)->ptr_duplicate());
+                // the copy should have read_p true to prevent the serialize() call
+                // below in the nested for loops from triggering a second call to
+                // read().
+                row->back()->set_read_p(true);
+                // Do not compute the checksum for constructor types; those
+                // types will compute the checksum on the values they contain.
+                // TODO Check on this
+                if (!row->back()->is_constructor_type()) row->back()->compute_checksum(checksum);
+            }
+        }
+        d_values.push_back(row);
+    }
+}
+
+/**
+ * @brief Serialize the values of a D4Sequence
+ * This method assumes that the underlying data store cannot/does not return a count
+ * of items separately from the items themselves. For a data store that does, this
+ * method should probably be specialized to take advantage of that. Because the DAP4
+ * spec requires that a sequence be prefixed by a count, this method reads the entire
+ * sequence into memory before sending it (and counts the number of elements in the
+ * the process). For a data store where the count is available a priori, this could
+ * be rewritten so that the count is sent and then each instance/element of the sequence
+ * sent in succession.
+ *
+ * If this method is specialized, once the data are loaded into the D4SeqValues instance,
+ * make sure to set d_length and make sure to set_read_p for each BaseType in D4SeqValues.
+ *
+ * @param m Stream data sink
+ * @param dmr DMR object for the evaluator
+ * @param eval CE Evaluator object
+ * @param filter True if the CE should be evaluated, false otherwise.
+ */
+void D4Sequence::serialize(D4StreamMarshaller &m, DMR &dmr, bool filter)
+{
+    // Read the data values, then serialize. NB: read_next_instance sets d_length.
+    while (read_next_instance(filter)) {
+        D4SeqRow *row = new D4SeqRow;
+        for (Vars_iter i = d_vars.begin(), e = d_vars.end(); i != e; i++) {
+            if ((*i)->send_p()) {
+                // store the variable's value.
+                row->push_back((*i)->ptr_duplicate());
+                // the copy should have read_p true to prevent the serialize() call
+                // below in the nested for loops from triggering a second call to
+                // read().
+                row->back()->set_read_p(true);
+            }
+        }
+        d_values.push_back(row);
+        DBG(cerr << "D4Sequence::serialize Added row" << endl);
+    }
+
+    // write D4Sequecne::length(); don't include the length in the checksum
+    m.put_count(d_length);
+    DBG(cerr << "D4Sequence::serialize count: " << d_length << endl);
+
+    // By this point the d_values object holds all and only the values to be sent;
+    // use the serialize methods to send them (but no need to test send_p).
+    for (D4SeqValues::iterator i = d_values.begin(), e = d_values.end(); i != e; ++i) {
+        for (D4SeqRow::iterator j = (*i)->begin(), f = (*i)->end(); j != f; ++j) {
+            (*j)->serialize(m, dmr, /*eval,*/false);
+        }
+    }
+}
+
+void D4Sequence::deserialize(D4StreamUnMarshaller &um, DMR &dmr)
+{
+    set_length(um.get_count());
+    DBG(cerr << "D4Sequence::deserialize count: " << d_length << endl);
+
+    for (int64_t i = 0; i < d_length; ++i) {
+        D4SeqRow *row = new D4SeqRow;
+        for (Vars_iter i = d_vars.begin(), e = d_vars.end(); i != e; ++i) {
+            (*i)->deserialize(um, dmr);
+            row->push_back((*i)->ptr_duplicate());
+        }
+        d_values.push_back(row);
+    }
+}
+
+#if INDEX_SUBSETTING
+/** 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 ending row number. The 20th row is row 19.
+ @param stride The stride. A stride of two skips every other row. */
+virtual void 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;
+}
+#endif
+
+/** @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. */
+D4SeqRow *
+D4Sequence::row_value(size_t row)
+{
+    if (row >= d_values.size()) return 0;
+    return d_values[row];
+}
+
+static bool base_type_name_eq(BaseType *btp, const string name)
+{
+    return btp->name() == name;
+}
+
+/** @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 *
+D4Sequence::var_value(size_t row_num, const string &name)
+{
+    D4SeqRow *row = row_value(row_num);
+    if (!row) return 0;
+
+    D4SeqRow::iterator elem = find_if(row->begin(), row->end(), bind2nd(ptr_fun(base_type_name_eq), name));
+    return (elem != row->end()) ? *elem : 0;
+}
+
+/** @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 *
+D4Sequence::var_value(size_t row_num, size_t i)
+{
+    D4SeqRow *row = row_value(row_num);
+    if (!row) return 0;
+
+    if (i >= row->size()) return 0;
+
+    return (*row)[i];
+}
+
+void D4Sequence::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) static_cast<D4Sequence*>(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) static_cast<D4Sequence*>(bt_ptr)->print_val_by_rows(out,
+                    space + "    ", false, print_row_num);
+            else
+                bt_ptr->print_val(out, space, false);
+        }
+    }
+
+    out << " }";
+}
+
+void D4Sequence::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 << "{ ";
+
+    if (length() != 0) {
+        int rows = length() - 1;	// -1 because the last row is treated specially
+        for (int i = 0; i < rows; ++i) {
+            print_one_row(out, i, space, print_row_numbers);
+            out << ", ";
+        }
+        print_one_row(out, rows, space, print_row_numbers);
+    }
+
+    out << " }";
+
+    if (print_decl_p) out << ";\n";
+}
+
+void D4Sequence::print_val(ostream &out, string space, bool print_decl_p)
+{
+    print_val_by_rows(out, space, print_decl_p, 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 D4Sequence::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Sequence::dump - (" << (void *) this << ")" << endl;
+    DapIndent::Indent();
+    Constructor::dump(strm);
+    strm << DapIndent::LMarg << "# rows deserialized: " << d_length << endl;
+    strm << DapIndent::LMarg << "bracket notation information:" << endl;
+
+    DapIndent::Indent();
+#if INDEX_SUBSETTING
+    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;
+#endif
+    DapIndent::UnIndent();
+
+    DapIndent::UnIndent();
+}
+
+} // namespace libdap
+
diff --git a/D4Sequence.h b/D4Sequence.h
new file mode 100644
index 0000000..e86efca
--- /dev/null
+++ b/D4Sequence.h
@@ -0,0 +1,272 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 _d4sequence_h
+#define _d4sequence_h 1
+
+#include "Constructor.h"
+
+// DAP2 Sequence supported subsetting using the array notation. This might
+// be introduced into DAP4 later on.
+#define INDEX_SUBSETTING 0
+
+class Crc32;
+
+namespace libdap
+{
+class BaseType;
+
+/** The type BaseTypeRow is used to store single rows of values in an
+    instance of D4Sequence. Values are stored in instances of BaseType. */
+typedef vector<BaseType *> D4SeqRow;
+
+/** This type holds all of the values of a D4Sequence. */
+typedef vector<D4SeqRow *> D4SeqValues;
+
+/** This is the interface for the class D4Sequence. A sequence contains
+    a single set of variables, all at the same lexical level just like
+    a Structure.  Like a Structure, a D4Sequence may contain other
+    compound types, including other D4Sequences.  Unlike a Structure, a
+    D4Sequence defines a pattern that is repeated N times for a sequence
+    of N elements. It is useful to think of a D4Sequence as representing
+    a table of values (like a relational database), with each row of
+    the table corresponding to a D4Sequence ``instance.''  (This usage
+    can be confusing, since ``instance'' also refers to a particular
+    item of class D4Sequence.)  For example:
+
+    <pre>
+    D4Sequence {
+      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 D4Sequence can be arbitrarily long, which is to say that its
+    length is not part of its declaration.  A D4Sequence can contain
+    other D4Sequences:
+
+    <pre>
+    D4Sequence {
+      String name;
+      Int32 age;
+      D4Sequence {
+        String friend;
+      } friend_list;
+    } person;
+    </pre>
+
+    <pre>
+    Fred       34     Norman
+                      Andrea
+                      Ralph
+                      Lisa
+    Ralph      23     Norman
+                      Andrea
+                      Lisa
+                      Marth
+                      Throckmorton
+                      Helga
+                      Millicent
+    Andrea     29     Ralph
+                      Natasha
+                      Norman
+    ...        ..     ...
+    </pre>
+
+    Internally, the D4Sequence is represented by a vector of vectors. The
+    members of the outer vector are the members of the D4Sequence. This
+    includes the nested D4Sequences, as in the above example.
+
+    Because the length of a D4Sequence is indeterminate, there are
+    changes to the behavior of the functions to read this class of
+    data.  The <tt>read()</tt> function for D4Sequence must be written so that
+    successive calls return values for successive rows of the D4Sequence.
+
+    Similar to a C structure, you refer to members of D4Sequence
+    elements with a ``.'' notation.  For example, if the D4Sequence has
+    a member D4Sequence called ``Tom'' and Tom has a member Float32
+    called ``shoe_size'', you can refer to Tom's shoe size as
+    ``Tom.shoe_size''.
+
+    @brief Holds a sequence. */
+
+class D4Sequence: public Constructor
+{
+private:
+
+protected:
+    // This holds the values of the sequence. Values are stored in
+    // instances of BaseTypeRow objects which hold instances of BaseType.
+    //
+    // Allow these values to be accessed by subclasses
+    D4SeqValues d_values;
+
+    int64_t d_length;	// How many elements are in the sequence; -1 if not currently known
+
+#if INDEX_SUBSETTING
+    int d_starting_row_number;
+    int d_row_stride;
+    int d_ending_row_number;
+#endif
+
+    void m_duplicate(const D4Sequence &s);
+
+    friend class D4SequenceTest;
+
+public:
+
+    D4Sequence(const string &n);
+    D4Sequence(const string &n, const string &d);
+
+    D4Sequence(const D4Sequence &rhs);
+
+    virtual ~D4Sequence();
+
+    D4Sequence &operator=(const D4Sequence &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    /**
+     * @brief The number of elements in a Sequence object.
+     * @note This is not the number of items in a row, but the number
+     * of rows in the complete sequence object.
+     *
+     * @return 0 if the number of elements is unknown, else
+     * return the number of elements.
+     */
+    virtual int length() const { return (int)d_length; }
+
+    /**
+     * Set the length of the sequence.
+     * @param count
+     */
+    virtual void set_length(int count) { d_length = (int64_t)count; }
+
+    virtual bool read_next_instance(/*DMR &dmr, ConstraintEvaluator &eval,*/ bool filter);
+
+    virtual void intern_data(ConstraintEvaluator &, DDS &) {
+    	throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4");
+    }
+    virtual bool serialize(ConstraintEvaluator &, DDS &, Marshaller &, bool ) {
+    	throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4");
+    }
+    virtual bool deserialize(UnMarshaller &, DDS *, bool ) {
+    	throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4");
+    }
+
+    // DAP4
+    virtual void intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator &eval*/);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
+#if INDEX_SUBSETTING
+    /** 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. */
+    virtual int get_starting_row_number() const { 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. */
+    virtual int get_row_stride() const { 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. */
+    virtual int get_ending_row_number() const { return d_ending_row_number; }
+
+    virtual void set_row_number_constraint(int start, int stop, int stride = 1);
+#endif
+
+    /**
+     * @brief Set the internal value.
+     * The 'values' of a D4Sequence is a vector of vectors of BaseType* objects.
+     * Using this method does not perform a deep copy; the BaseType*s are
+     * copied so the caller should not free them. Note that this does set
+     * d_length but the read_p flag for the BaseTypes should all be set to
+     * keep the serializer from trying to read each of them.
+     * @param values
+     */
+    virtual void set_value(D4SeqValues &values) { d_values = values; d_length = d_values.size(); }
+
+    /**
+     * @brief Get the values for this D4Sequence
+     * This method does not perform a deep copy of the values so the caller
+     * should not free the BaseType*s in this vector of vectors since this
+     * object will free those in its destructor.
+     * @return The entire vector of vector of BaseType*
+     */
+    virtual D4SeqValues value() const { return d_values; }
+
+    virtual D4SeqRow *row_value(size_t row);
+    virtual BaseType *var_value(size_t row, const string &name);
+    virtual BaseType *var_value(size_t row, size_t i);
+
+    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);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif //_sequence_h
diff --git a/DAP4StreamMarshaller.cc b/D4StreamMarshaller.cc
similarity index 53%
rename from DAP4StreamMarshaller.cc
rename to D4StreamMarshaller.cc
index b4907bd..ce90315 100644
--- a/DAP4StreamMarshaller.cc
+++ b/D4StreamMarshaller.cc
@@ -1,4 +1,4 @@
-// DAP4StreamMarshaller.cc
+// D4StreamMarshaller.cc
 
 // -*- mode: c++; c-basic-offset:4 -*-
 
@@ -20,56 +20,38 @@
 //
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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.
-//
-// Portions of this code are from Google's great protocol buffers library and
-// are copyrighted as follows:
-
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://code.google.com/p/protobuf/
-
 
-#include "DAP4StreamMarshaller.h"
+#include "config.h"
 
-#include <stdint.h>     // for the Google protobuf code
 #include <byteswap.h>
+#include <cassert>
 
 #include <iostream>
 #include <sstream>
 #include <iomanip>
-
-using namespace std;
+#include <limits>
 
 //#define DODS_DEBUG 1
 
-#include "dods-datatypes.h"
-#include "util.h"
-#include "debug.h"
-
-namespace libdap {
-
-static inline bool is_host_big_endian()
-{
-#ifdef COMPUTE_ENDIAN_AT_RUNTIME
+#include "D4StreamMarshaller.h"
 
-    dods_int16 i = 0x0100;
-    char *c = reinterpret_cast<char*>(&i);
-    return *c;
+#if USE_XDR_FOR_IEEE754_ENCODING
+#include "XDRUtils.h"
+#include "util.h"
+#endif
 
-#else
+#include "debug.h"
 
-#ifdef WORDS_BIGENDIAN
-    return true;
-#else
-    return false;
-#endif
+using namespace std;
 
-#endif
-}
+namespace libdap {
 
+#if 0
+// We decided to use int64_t to represent sizes of both arrays and strings,
+// So this code is not used. jhrg 10/4/13
 
 // From the Google protobuf library
 inline uint8_t* WriteVarint64ToArrayInline(uint64_t value, uint8_t* target) {
@@ -142,129 +124,132 @@ inline uint8_t* WriteVarint64ToArrayInline(uint64_t value, uint8_t* target) {
   target[size-1] &= 0x7F;
   return target + size;
 }
+#endif
+
+#if USE_XDR_FOR_IEEE754_ENCODING
+/**
+ * @todo recode this so that it does not copy data to a new buffer but
+ * serializes directly to the stream (element by element) and compare the
+ * run times.
+ */
+void D4StreamMarshaller::m_serialize_reals(char *val, unsigned int num, int width, Type type)
+{
+    dods_uint64 size = num * width;
+    // char *buf = (char*)malloc(size); jhrg 7/23/13
+    vector<char> buf(size);
+    XDR xdr;
+    xdrmem_create(&xdr, &buf[0], size, XDR_ENCODE);
+    try {
+        if(!xdr_array(&xdr, &val, (unsigned int *)&num, size, width, XDRUtils::xdr_coder(type)))
+            throw InternalErr(__FILE__, __LINE__, "Error serializing a Float64 array");
 
-/** Build an instance of DAP4StreamMarshaller. Bind the C++ stream out to this
- * instance. If the checksum parameter is true, initialize a checksum buffer
- * and enable the use of the reset_checksum() and get_checksum() methods.
+        if (xdr_getpos(&xdr) != size)
+            throw InternalErr(__FILE__, __LINE__, "Error serializing a Float64 array");
+
+        // If this is a little-endian host, twiddle the bytes
+        static bool twiddle_bytes = !is_host_big_endian();
+        if (twiddle_bytes) {
+            if (width == 4) {
+                dods_float32 *lbuf = reinterpret_cast<dods_float32*>(&buf[0]);
+                while (num--) {
+                    dods_int32 *i = reinterpret_cast<dods_int32*>(lbuf++);
+                    *i = bswap_32(*i);
+                }
+            }
+            else { // width == 8
+                dods_float64 *lbuf = reinterpret_cast<dods_float64*>(&buf[0]);
+                while (num--) {
+                    dods_int64 *i = reinterpret_cast<dods_int64*>(lbuf++);
+                    *i = bswap_64(*i);
+                }
+            }
+        }
+
+        d_out.write(&buf[0], size);
+    }
+    catch (...) {
+        xdr_destroy(&xdr);
+        throw;
+    }
+    xdr_destroy(&xdr);
+}
+#endif
+
+/** Build an instance of D4StreamMarshaller. Bind the C++ stream out to this
+ * instance. If the write_data parameter is true, write the data in addition
+ * to computing and sending the checksum.
  *
  * @param out Write to this stream object.
  * @param write_data If true, write data values. True by default
  */
-DAP4StreamMarshaller::DAP4StreamMarshaller(ostream &out, bool write_data) :
-        d_out(out), d_ctx(0), d_write_data(write_data), d_checksum_ctx_valid(false)
+D4StreamMarshaller::D4StreamMarshaller(ostream &out, bool write_data) :
+        d_out(out), d_write_data(write_data)
 {
+	assert(sizeof(std::streamsize) >= sizeof(int64_t));
+
+#if USE_XDR_FOR_IEEE754_ENCODING
     // XDR is used if the call std::numeric_limits<double>::is_iec559()
     // returns false indicating that the compiler is not using IEEE 754.
-    // If it is, we just write out the bytes. Why malloc()? Because
-    // xdr_destroy is going to call free() for us.
-    d_ieee754_buf = (char*)malloc(sizeof(dods_float64));
-    if (!d_ieee754_buf)
-        throw InternalErr(__FILE__, __LINE__, "Could not create DAP4StreamMarshaller");
+    // If it is, we just write out the bytes.
     xdrmem_create(&d_scalar_sink, d_ieee754_buf, sizeof(dods_float64), XDR_ENCODE);
+#endif
 
     // This will cause exceptions to be thrown on i/o errors. The exception
     // will be ostream::failure
     out.exceptions(ostream::failbit | ostream::badbit);
-
-    d_ctx = EVP_MD_CTX_create();
 }
 
-DAP4StreamMarshaller::~DAP4StreamMarshaller()
+D4StreamMarshaller::~D4StreamMarshaller()
 {
-    // Free the buffer this contains. The xdr_destroy() macro does not
-    // free the XDR struct (which is fine since we did not dynamically
-    // allocate it).
-    xdr_destroy (&d_scalar_sink);
-
-    EVP_MD_CTX_destroy(d_ctx);
-}
-
-/**
- * Return the is the host big- or little-endian?
- *
- * @return 'big' or ' little'.
- */
-
-string
-DAP4StreamMarshaller::get_endian() const
-{
-    return (is_host_big_endian()) ? "big": "little";
+#if USE_XDR_FOR_IEEE754_ENCODING
+    xdr_destroy(&d_scalar_sink);
+#endif
 }
 
 /** Initialize the checksum buffer. This resets the checksum calculation.
- * @exception InternalErr if called when the object was created without
- * checksum support.
  */
-void DAP4StreamMarshaller::reset_checksum()
+void D4StreamMarshaller::reset_checksum()
 {
-    if (EVP_DigestInit_ex(d_ctx, EVP_md5(), 0) == 0)
-        throw Error("Failed to initialize checksum object.");
-
-    d_checksum_ctx_valid = true;
+    d_checksum.Reset();
 }
 
 /**
- * Private method to compute the checksum.
- */
-void DAP4StreamMarshaller::m_compute_checksum()
-{
-    if (d_checksum_ctx_valid) {
-        // '...Final()' 'erases' the context so the next call without a reset
-        // returns a bogus value.
-        d_checksum_ctx_valid = false;
-
-        // For MD5, the array md holds the 16 digits of the hash as values.
-        // The loop below turns that into a nice 32-digit hex number; see
-        // put_checksum() for a version that writes the 128-bit value without
-        // that conversion.
-        unsigned int md_len;
-        int status = EVP_DigestFinal_ex(d_ctx, &d_md[0], &md_len);
-        if (status == 0 || md_len != c_md5_length)
-            throw Error("Error computing the checksum (checksum computation).");
-    }
-}
-
-/** Get the current checksum. It is not possible to continue computing the
+ * Get the current checksum. It is not possible to continue computing the
  * checksum once this has been called.
- * @exception InternalErr if called when the object was created without
- * checksum support or if called when the checksum has already been returned.
+ *
+ * @note This method is not intended to be called often or for inserting the
+ * checksum into an I/O stream; see put_checksum(). This is intended for
+ * instrumentation code.
+ *
+ * @return The checksum in a string object that always has eight characters.
  */
-string DAP4StreamMarshaller::get_checksum()
+string D4StreamMarshaller::get_checksum()
 {
-    if (d_checksum_ctx_valid) {
-        m_compute_checksum();
-    }
-
     ostringstream oss;
     oss.setf(ios::hex, ios::basefield);
-    for (unsigned int i = 0; i < c_md5_length; ++i) {
-        oss << setfill('0') << setw(2) << (unsigned int) d_md[i];
-    }
+    oss << setfill('0') << setw(8) << d_checksum.GetCrc32();
 
     return oss.str();
 }
 
-void DAP4StreamMarshaller::put_checksum()
+/**
+ * @brief Write the checksum
+ * Write the checksum for the data sent since the last call to reset_checksum()
+ * to the I/O stream associated with this marshaller. Use this to send the
+ * checksum, not get_checksum().
+ */
+void D4StreamMarshaller::put_checksum()
 {
-    if (d_checksum_ctx_valid) {
-        m_compute_checksum();
-    }
-
-    d_out.write(reinterpret_cast<char*>(&d_md[0]), c_md5_length);
+    Crc32::checksum chk = d_checksum.GetCrc32();
+    d_out.write(reinterpret_cast<char*>(&chk), sizeof(Crc32::checksum));
 }
 
-void DAP4StreamMarshaller::checksum_update(const void *data, unsigned long len)
+void D4StreamMarshaller::checksum_update(const void *data, unsigned long len)
 {
-    if (!d_checksum_ctx_valid)
-        throw InternalErr(__FILE__, __LINE__, "Invalid checksum context (checksum update).");
-
-    if (EVP_DigestUpdate(d_ctx, data, len) == 0) {
-        d_checksum_ctx_valid = false;
-        throw Error("Error computing the checksum (checksum update).");
-    }
+    d_checksum.AddData(reinterpret_cast<const uint8_t*>(data), len);
 }
 
-void DAP4StreamMarshaller::put_byte(dods_byte val)
+void D4StreamMarshaller::put_byte(dods_byte val)
 {
     checksum_update(&val, sizeof(dods_byte));
 
@@ -275,7 +260,7 @@ void DAP4StreamMarshaller::put_byte(dods_byte val)
     }
 }
 
-void DAP4StreamMarshaller::put_int8(dods_int8 val)
+void D4StreamMarshaller::put_int8(dods_int8 val)
 {
     checksum_update(&val, sizeof(dods_int8));
 
@@ -286,7 +271,7 @@ void DAP4StreamMarshaller::put_int8(dods_int8 val)
     }
 }
 
-void DAP4StreamMarshaller::put_int16(dods_int16 val)
+void D4StreamMarshaller::put_int16(dods_int16 val)
 {
     checksum_update(&val, sizeof(dods_int16));
 
@@ -294,7 +279,7 @@ void DAP4StreamMarshaller::put_int16(dods_int16 val)
         d_out.write(reinterpret_cast<char*>(&val), sizeof(dods_int16));
 }
 
-void DAP4StreamMarshaller::put_int32(dods_int32 val)
+void D4StreamMarshaller::put_int32(dods_int32 val)
 {
     checksum_update(&val, sizeof(dods_int32));
 
@@ -302,21 +287,32 @@ void DAP4StreamMarshaller::put_int32(dods_int32 val)
         d_out.write(reinterpret_cast<char*>(&val), sizeof(dods_int32));
 }
 
-void DAP4StreamMarshaller::put_int64(dods_int64 val)
+void D4StreamMarshaller::put_int64(dods_int64 val)
 {
     checksum_update(&val, sizeof(dods_int64));
 
     if (d_write_data)
-        d_out.write(reinterpret_cast<char*>(&val), sizeof(dods_int64));
+        d_out.write(reinterpret_cast<const char*>(&val), sizeof(dods_int64));
 }
 
-void DAP4StreamMarshaller::put_float32(dods_float32 val)
+void D4StreamMarshaller::put_float32(dods_float32 val)
 {
+#if !USE_XDR_FOR_IEEE754_ENCODING
+	assert(std::numeric_limits<float>::is_iec559);
+
     checksum_update(&val, sizeof(dods_float32));
 
+    if (d_write_data)
+    	d_out.write(reinterpret_cast<const char*>(&val), sizeof(dods_float32));
+
+#else
+    // This code uses XDR to convert from a local representation to IEEE754;
+    // The extra 'twiddle' operation makes the byte-order correct for this
+    // host should it not be big-endian. Also note the assert() at the
+    // start of the method.
+
     if (d_write_data) {
         if (std::numeric_limits<float>::is_iec559 ) {
-            DBG2(cerr << "Native rep is ieee754." << endl);
             d_out.write(reinterpret_cast<char*>(&val), sizeof(dods_float32));
         }
         else {
@@ -339,12 +335,21 @@ void DAP4StreamMarshaller::put_float32(dods_float32 val)
             d_out.write(d_ieee754_buf, sizeof(dods_float32));
         }
     }
+#endif
 }
 
-void DAP4StreamMarshaller::put_float64(dods_float64 val)
+void D4StreamMarshaller::put_float64(dods_float64 val)
 {
+#if !USE_XDR_FOR_IEEE754_ENCODING
+	assert(std::numeric_limits<double>::is_iec559);
+
     checksum_update(&val, sizeof(dods_float64));
 
+    if (d_write_data)
+    	d_out.write(reinterpret_cast<const char*>(&val), sizeof(dods_float64));
+
+#else
+    // See the comment above in put_float32()
     if (d_write_data) {
         if (std::numeric_limits<double>::is_iec559)
             d_out.write(reinterpret_cast<char*>(&val), sizeof(dods_float64));
@@ -368,9 +373,10 @@ void DAP4StreamMarshaller::put_float64(dods_float64 val)
             d_out.write(d_ieee754_buf, sizeof(dods_float64));
         }
     }
+#endif
 }
 
-void DAP4StreamMarshaller::put_uint16(dods_uint16 val)
+void D4StreamMarshaller::put_uint16(dods_uint16 val)
 {
     checksum_update(&val, sizeof(dods_uint16));
 
@@ -378,7 +384,7 @@ void DAP4StreamMarshaller::put_uint16(dods_uint16 val)
         d_out.write(reinterpret_cast<char*>(&val), sizeof(dods_uint16));
 }
 
-void DAP4StreamMarshaller::put_uint32(dods_uint32 val)
+void D4StreamMarshaller::put_uint32(dods_uint32 val)
 {
     checksum_update(&val, sizeof(dods_uint32));
 
@@ -386,7 +392,7 @@ void DAP4StreamMarshaller::put_uint32(dods_uint32 val)
         d_out.write(reinterpret_cast<char*>(&val), sizeof(dods_uint32));
 }
 
-void DAP4StreamMarshaller::put_uint64(dods_uint64 val)
+void D4StreamMarshaller::put_uint64(dods_uint64 val)
 {
     checksum_update(&val, sizeof(dods_uint64));
 
@@ -394,153 +400,203 @@ void DAP4StreamMarshaller::put_uint64(dods_uint64 val)
         d_out.write(reinterpret_cast<char*>(&val), sizeof(dods_uint64));
 }
 
+/**
+ * Used only for Sequences, where the count must be added to the stream
+ * and then the fields sent using separate calls to methods here. The
+ * methods put_opaque_dap4(), ..., that need counts sent as prefixes to
+ * their data handle it themselves.
+ *
+ * @param count How many elements follow.
+ */
+void D4StreamMarshaller::put_count(int64_t count)
+{
+	d_out.write(reinterpret_cast<const char*>(&count), sizeof(int64_t));
+}
 
-void DAP4StreamMarshaller::put_str(const string &val)
+void D4StreamMarshaller::put_str(const string &val)
 {
     checksum_update(val.c_str(), val.length());
 
     if (d_write_data) {
-        put_length_prefix(val.length());
+    	int64_t len = val.length();
+
+    	d_out.write(reinterpret_cast<const char*>(&len), sizeof(int64_t));
         d_out.write(val.data(), val.length());
     }
 }
 
-void DAP4StreamMarshaller::put_url(const string &val)
+void D4StreamMarshaller::put_url(const string &val)
 {
     put_str(val);
 }
 
-void DAP4StreamMarshaller::put_opaque(char *val, unsigned int len)
+void D4StreamMarshaller::put_opaque_dap4(const char *val, int64_t len)
 {
     checksum_update(val, len);
 
     if (d_write_data) {
-        put_length_prefix(len);
+    	d_out.write(reinterpret_cast<const char*>(&len), sizeof(int64_t));
         d_out.write(val, len);
     }
 }
 
-void DAP4StreamMarshaller::put_length_prefix(dods_uint64 val)
+/**
+ * @brief Write a fixed size vector
+ * @param val Pointer to the data
+ * @param num Number of bytes to write
+ */
+void D4StreamMarshaller::put_vector(char *val, int64_t num_bytes)
 {
-    if (d_write_data) {
-        DBG2(cerr << "val: " << val << endl);
-
-        vector<uint8_t> target(sizeof(dods_uint64) + 1, 0);
-        uint8_t* to_send = WriteVarint64ToArrayInline(val, &target[0]);
-        d_out.write(reinterpret_cast<char*>(&target[0]), to_send - &target[0]);
+    checksum_update(val, num_bytes);
 
-        DBG2(cerr << "varint: " << hex << *(uint64_t*)&target[0] << dec << endl);
-    }
+    if (d_write_data)
+        d_out.write(val, num_bytes);
 }
 
-void DAP4StreamMarshaller::put_vector(char *val, unsigned int num)
+void D4StreamMarshaller::put_vector(char *val, int64_t num_elem, int elem_size)
 {
-    checksum_update(val, num);
+	assert(val);
+	assert(num_elem >= 0);
+	assert(elem_size > 0);
+
+	int64_t bytes;
+
+	switch (elem_size) {
+	case 1:
+		assert(!"Don't call this method for bytes, use put_vector(val, bytes) instead");
+		bytes = num_elem;
+		break;
+	case 2:
+		// Don't bother testing the sign bit
+		assert(!(num_elem & 0x4000000000000000)); // 0x 40 00 --> 0100 0000
+		bytes = num_elem << 1;
+		break;
+	case 4:
+		assert(!(num_elem & 0x6000000000000000)); // 0x 60 00 --> 0110 0000
+		bytes = num_elem << 2;
+		break;
+	case 8:
+		assert(!(num_elem & 0x7000000000000000)); // 0111 0000
+		bytes = num_elem << 3;
+		break;
+	default:
+		bytes = num_elem * elem_size;
+		break;
+	}
+
+    checksum_update(val, bytes);
 
-    d_out.write(val, num);
+    if (d_write_data)
+    	d_out.write(val, bytes);
 }
 
 /**
- * Write a vector of values prefixed by the number of elements. This is a
- * special version for vectors of bytes and it calls put_opaque()
- *
- * @note This function writes the number of elements in the vector which,
- * in this case, is equal to the number of bytes
- *
- * @param val Pointer to the data to write
- * @param num The number of elements to write
+ * @brief Write a fixed size vector
+ * @note This method and its companion for float64 exists in case we need to
+ * support machine that do not use IEEE754 for their floating point representation.
+ * @param val Pointer to the data
+ * @param num Number of elements
+ * @param width Size of a single element
+ * @param type DAP variable type; used to handle float32 and float64 types correctly
  */
-void DAP4StreamMarshaller::put_varying_vector(char *val, unsigned int num)
+void D4StreamMarshaller::put_vector_float32(char *val, int64_t num_elem)
 {
-    put_opaque(val, num);
-}
+#if !USE_XDR_FOR_IEEE754_ENCODING
 
-/**
- * @todo recode this so that it does not copy data to a new buffer but
- * serializes directly to the stream (element by element) and compare the
- * run times.
- */
-void DAP4StreamMarshaller::m_serialize_reals(char *val, unsigned int num, int width, Type type)
-{
-    dods_uint64 size = num * width;
-    // This is a leak!!! xdr_destroy does not free 'buf'.
-    //char *buf = (char*)malloc(size);
-    vector<char> buf(size);
-    XDR xdr;
-    xdrmem_create(&xdr, &buf[0], size, XDR_ENCODE);
-    try {
-        if(!xdr_array(&xdr, &val, (unsigned int *)&num, size, width, XDRUtils::xdr_coder(type)))
-            throw InternalErr(__FILE__, __LINE__, "Error serializing a Float64 array");
+	assert(std::numeric_limits<float>::is_iec559);
+	assert(val);
+	assert(num_elem >= 0);
+	// sizeof() a 32-bit float is 4, so we're going to send 4 * num_elem bytes, so
+	// make sure that doesn't overflow a 63-bit integer (the max positive value in
+	// a signed int64; use 1110 0000 0.. (0xe000 ...) to mask for non-zero bits
+	// to test that num can be multiplied by 4. A
+	assert(!(num_elem & 0xe000000000000000));
 
-        if (xdr_getpos(&xdr) != size)
-            throw InternalErr(__FILE__, __LINE__, "Error serializing a Float64 array");
+	num_elem = num_elem << 2;	// num_elem is now the number of bytes
 
-        // If this is a little-endian host, twiddle the bytes
-        static bool twiddle_bytes = !is_host_big_endian();
-        if (twiddle_bytes) {
-            if (width == 4) {
-                dods_float32 *lbuf = reinterpret_cast<dods_float32*>(&buf[0]);
-                while (num--) {
-                    dods_int32 *i = reinterpret_cast<dods_int32*>(lbuf++);
-                    *i = bswap_32(*i);
-                }
-            }
-            else { // width == 8
-                dods_float64 *lbuf = reinterpret_cast<dods_float64*>(&buf[0]);
-                while (num--) {
-                    dods_int64 *i = reinterpret_cast<dods_int64*>(lbuf++);
-                    *i = bswap_64(*i);
-                }
-            }
-        }
+    checksum_update(val, num_elem);
 
-        d_out.write(&buf[0], size);
-    }
-    catch (...) {
-        xdr_destroy(&xdr);
-        throw;
-    }
-    xdr_destroy(&xdr);
-}
+    if (d_write_data)
+    	d_out.write(val, num_elem);
 
-void DAP4StreamMarshaller::put_vector(char *val, unsigned int num, int width, Type type)
-{
-    checksum_update(val, num * width);
+#else
+	assert(val);
+	assert(num_elem >= 0);
+	// sizeof() a 32-bit float is 4, so we're going to send 4 * num_elem bytes, so
+	// make sure that doesn't overflow a 63-bit integer (the max positive value in
+	// a signed int64; use 1110 0000 0.. (0xe000 ...) to mask for non-zero bits
+	// to test that num can be multiplied by 4. A
+	assert(!(num_elem & 0xe000000000000000));
+
+	int64_t bytes = num_elem << 2;	// num_elem is now the number of bytes
+
+    checksum_update(val, bytes);
 
     if (d_write_data) {
-        if (type == dods_float32_c && !std::numeric_limits<float>::is_iec559) {
+        if (!std::numeric_limits<float>::is_iec559) {
             // If not using IEEE 754, use XDR to get it that way.
-            m_serialize_reals(val, num, 4, type);
-        }
-        else if (type == dods_float64_c && !std::numeric_limits<double>::is_iec559) {
-            m_serialize_reals(val, num, 8, type);
+            m_serialize_reals(val, num_elem, 4, type);
         }
         else {
-            d_out.write(val, num * width);
+            d_out.write(val, bytes);
         }
     }
+#endif
 }
 
 /**
- * Write a vector of values prefixed by the number of elements.
- *
- * @note This function writes the number of elements in the vector, not the
- * number of bytes.
+ * @brief Write a fixed size vector of float64s
  *
- * @param val Pointer to the data to write
- * @param num The number of elements to write
- * @param width The number of bytes in each element
- * @param type The DAP type code (used only for float32 and float64 values).
+ * @param val Pointer to the data
+ * @param num Number of elements
+ * @param width Size of a single element
+ * @param type DAP variable type; used to handle float32 and float64 types correctly
  */
-void DAP4StreamMarshaller::put_varying_vector(char *val, unsigned int num, int width, Type type)
+void D4StreamMarshaller::put_vector_float64(char *val, int64_t num_elem)
 {
-    put_length_prefix(num);
-    put_vector(val, num, width, type);
+#if !USE_XDR_FOR_IEEE754_ENCODING
+
+	assert(std::numeric_limits<double>::is_iec559);
+	assert(val);
+	assert(num_elem >= 0);
+	// See comment above
+	assert(!(num_elem & 0xf000000000000000));
+
+	num_elem = num_elem << 3;	// num_elem is now the number of bytes
+
+    checksum_update(val, num_elem);
+
+    if (d_write_data)
+    	d_out.write(val, num_elem);
+#else
+	assert(val);
+	assert(num_elem >= 0);
+	// sizeof() a 32-bit float is 4, so we're going to send 4 * num_elem bytes, so
+	// make sure that doesn't overflow a 63-bit integer (the max positive value in
+	// a signed int64; use 1110 0000 0.. (0xe000 ...) to mask for non-zero bits
+	// to test that num can be multiplied by 4. A
+	assert(!(num_elem & 0xe000000000000000));
+
+	int64_t bytes = num_elem << 3;	// num_elem is now the number of bytes
+
+    checksum_update(val, bytes);
+
+    if (d_write_data) {
+        if (!std::numeric_limits<double>::is_iec559) {
+            // If not using IEEE 754, use XDR to get it that way.
+            m_serialize_reals(val, num_elem, 8, type);
+        }
+        else {
+            d_out.write(val, bytes);
+        }
+    }
+#endif
+
 }
 
-void DAP4StreamMarshaller::dump(ostream &strm) const
+void D4StreamMarshaller::dump(ostream &strm) const
 {
-    strm << DapIndent::LMarg << "DAP4StreamMarshaller::dump - (" << (void *) this << ")" << endl;
+    strm << DapIndent::LMarg << "D4StreamMarshaller::dump - (" << (void *) this << ")" << endl;
 }
 
 } // namespace libdap
diff --git a/DAP4StreamMarshaller.h b/D4StreamMarshaller.h
similarity index 56%
rename from DAP4StreamMarshaller.h
rename to D4StreamMarshaller.h
index 22d750a..10f8de0 100644
--- a/DAP4StreamMarshaller.h
+++ b/D4StreamMarshaller.h
@@ -1,4 +1,4 @@
-// DAP4StreamMarshaller.h
+// D4StreamMarshaller.h
 
 // -*- mode: c++; c-basic-offset:4 -*-
 
@@ -21,22 +21,37 @@
 //
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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 I_DAP4StreamMarshaller_h
-#define I_DAP4StreamMarshaller_h 1
+#ifndef I_D4StreamMarshaller_h
+#define I_D4StreamMarshaller_h 1
 
 #include <iostream>
 
-#include <openssl/evp.h>
-
-using std::ostream;
-using std::cout;
+// By default, only support platforms that use IEEE754 for floating point values.
+// Hacked up code leftover from an older version of the class; largely untested.
+// jhrg 10/3/13
+#define USE_XDR_FOR_IEEE754_ENCODING 0
+
+#if USE_XDR_FOR_IEEE754_ENCODING
+#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
+#endif
+
+#include <stdint.h>
+#include "crc.h"
 
 #include "Marshaller.h"
-#include "XDRUtils.h"
+#include "InternalErr.h"
 
 namespace libdap {
 
@@ -51,54 +66,39 @@ class Vector;
  * @note This class uses the Marshaller interface; it could be rewritten
  * to use far fewer methods since all of the put_*() methods take different
  * types.
- *
- * @todo Add to configure a test for Apple's Common Crypto (man CC_MD5_Init)
- * and use that if present. ...drop in replacement for SSL MD5 functions. Why
- * Apple did this is a mystery.
  */
-class DAP4StreamMarshaller: public Marshaller {
-public:
-    const static unsigned int c_md5_length = 16;
+class D4StreamMarshaller: public Marshaller {
 
 private:
+#if USE_XDR_FOR_IEEE754_ENCODING
     XDR d_scalar_sink;
-    char * d_ieee754_buf; // used to serialize a float or double
-
-    ostream & d_out;
+    char d_ieee754_buf[sizeof(dods_float64)]; // used to serialize a float or double
+#endif
 
-    EVP_MD_CTX * d_ctx; // jhrg 4/24/12
+    ostream &d_out;
     bool d_write_data; // jhrg 1/27/12
-    bool d_checksum_ctx_valid;
-    unsigned char d_md[c_md5_length];
 
-    // These are private so they won't ever get used.
+    Crc32 d_checksum;
 
-    DAP4StreamMarshaller() : d_out(cout) {
-        throw InternalErr( __FILE__, __LINE__, "not implemented." ) ;
-    }
-    DAP4StreamMarshaller(const DAP4StreamMarshaller &) : Marshaller(), d_out(cout) {
-        throw InternalErr( __FILE__, __LINE__, "not implemented." ) ;
-    }
-    DAP4StreamMarshaller & operator=(const DAP4StreamMarshaller &) {
-        throw InternalErr( __FILE__, __LINE__, "not implemented." ) ;
-    }
+    // These are private so they won't ever get used.
+    D4StreamMarshaller();
+    D4StreamMarshaller(const D4StreamMarshaller &);
+    D4StreamMarshaller & operator=(const D4StreamMarshaller &);
 
-    void m_serialize_reals(char *val, unsigned int num, int width, Type type);
-    void m_compute_checksum();
+#if USE_XDR_FOR_IEEE754_ENCODING
+    void m_serialize_reals(char *val, int64_t num, int width, Type type);
+#endif
 
 public:
-    DAP4StreamMarshaller(ostream &out, bool write_data = true);
-    virtual ~DAP4StreamMarshaller();
+    D4StreamMarshaller(std::ostream &out, bool write_data = true);
+    virtual ~D4StreamMarshaller();
 
-    // Added here
-    virtual bool checksums() const {
-        return d_ctx != 0;
-    }
-    virtual string get_endian() const;
     virtual void reset_checksum();
     virtual string get_checksum();
     virtual void checksum_update(const void *data, unsigned long len);
-    void put_checksum();
+
+    virtual void put_checksum();
+    virtual void put_count(int64_t count);
 
     virtual void put_byte(dods_byte val);
     virtual void put_int8(dods_int8 val);
@@ -119,24 +119,21 @@ public:
     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_opaque(char *, unsigned int) {
+    	throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4; use put_opaque_dap4() instead.");
+    }
+
+    virtual void put_opaque_dap4(const char *val, int64_t len);
 
-    // Never use put_int() to send length information in DAP4, use
-    // put_length_prefix() instead.
+    // Never use put_int() to send length information in DAP4.
     virtual void put_int(int) {
         throw InternalErr(__FILE__, __LINE__, "Not Implemented; use put_length_prefix.");
     }
 
-    // Added; This method does not add its argument to the checksum;
-    // put_uint64() does.
-    //virtual void    put_length_prefix( dods_uint32 val ) ;
-    virtual void put_length_prefix(dods_uint64 val);
-
-    virtual void put_vector(char *val, unsigned int num);
-    virtual void put_vector(char *val, unsigned int num, int width, Type type);
-
-    virtual void put_varying_vector(char *val, unsigned int num);
-    virtual void put_varying_vector(char *val, unsigned int num, int width, Type type);
+    virtual void put_vector(char *val, int64_t num_bytes);
+    virtual void put_vector(char *val, int64_t num_elem, int elem_size);
+    virtual void put_vector_float32(char *val, int64_t num_elem);
+    virtual void put_vector_float64(char *val, int64_t num_elem);
 
     virtual void put_vector(char *, int , Vector &) {
         throw InternalErr(__FILE__, __LINE__, "Not Implemented; use put_length_prefix.");
@@ -145,10 +142,9 @@ public:
         throw InternalErr(__FILE__, __LINE__, "Not Implemented; use put_length_prefix.");
     }
 
-
-    virtual void dump(ostream &strm) const;
+    virtual void dump(std::ostream &strm) const;
 };
 
 } // namespace libdap
 
-#endif // I_DAP4StreamMarshaller_h
+#endif // I_D4StreamMarshaller_h
diff --git a/D4StreamUnMarshaller.cc b/D4StreamUnMarshaller.cc
new file mode 100644
index 0000000..c7ec806
--- /dev/null
+++ b/D4StreamUnMarshaller.cc
@@ -0,0 +1,475 @@
+// D4StreamUnMarshaller.cc
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2012 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 <byteswap.h>
+#include <cassert>
+
+#include <iostream>
+#include <iomanip>
+#include <limits>
+#include <string>
+#include <sstream>
+
+//#define DODS_DEBUG2 1
+//#define DODS_DEBUG 1
+
+#include "util.h"
+//#include "XDRUtils.h"
+#include "InternalErr.h"
+#include "D4StreamUnMarshaller.h"
+#include "debug.h"
+
+namespace libdap {
+
+/**
+ * @brief Build a DAP4 Stream unMarshaller.
+ *
+ * Build a DAP4 Stream UnMarshaller initialed to read from am istream object.
+ * Figure out if the words read for values need to be 'twiddled' based on the
+ * byte-order of the stream an this host (see set_twiddle_bytes()).
+ *
+ * @param in Read from this input stream
+ * @param is_stream_bigendian The byte order of the data in the stream
+ */
+D4StreamUnMarshaller::D4StreamUnMarshaller(istream &in, bool twiddle_bytes) : d_in( in ), d_twiddle_bytes(twiddle_bytes)
+{
+	assert(sizeof(std::streamsize) >= sizeof(int64_t));
+
+#if USE_XDR_FOR_IEEE754_ENCODING
+	// XDR is used to handle transforming non-ieee754 reals, nothing else.
+    xdrmem_create(&d_source, d_buf, sizeof(dods_float64), XDR_DECODE);
+#endif
+
+    // This will cause exceptions to be thrown on i/o errors. The exception
+    // will be ostream::failure
+    d_in.exceptions(istream::failbit | istream::badbit);
+
+}
+
+/**
+ * When using this constructor, set_twiddle_bytes() should be called
+ * before data are processed.
+ *
+ * @param in
+ */
+D4StreamUnMarshaller::D4StreamUnMarshaller(istream &in) : d_in( in ), d_twiddle_bytes(false)
+{
+	assert(sizeof(std::streamsize) >= sizeof(int64_t));
+
+#if USE_XDR_FOR_IEEE754_ENCODING
+    // XDR is used to handle transforming non-ieee754 reals, nothing else.
+    xdrmem_create(&d_source, d_buf, sizeof(dods_float64), XDR_DECODE);
+#endif
+
+    // This will cause exceptions to be thrown on i/o errors. The exception
+    // will be ostream::failure
+    d_in.exceptions(istream::failbit | istream::badbit);
+}
+
+D4StreamUnMarshaller::~D4StreamUnMarshaller( )
+{
+#if USE_XDR_FOR_IEEE754_ENCODING
+    xdr_destroy(&d_source);
+#endif
+}
+
+Crc32::checksum D4StreamUnMarshaller::get_checksum()
+{
+    Crc32::checksum c;
+    d_in.read(reinterpret_cast<char*>(&c), sizeof(Crc32::checksum));
+
+    return c;
+}
+
+string D4StreamUnMarshaller::get_checksum_str()
+{
+    ostringstream oss;
+    oss.setf(ios::hex, ios::basefield);
+    oss << setfill('0') << setw(8) << get_checksum();
+
+    return oss.str();
+}
+
+void
+D4StreamUnMarshaller::get_byte( dods_byte &val )
+{
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_byte));
+}
+
+void
+D4StreamUnMarshaller::get_int8( dods_int8 &val )
+{
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int8));
+}
+
+void
+D4StreamUnMarshaller::get_int16( dods_int16 &val )
+{
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int16));
+    if (d_twiddle_bytes)
+        val = bswap_16(val);
+}
+
+void
+D4StreamUnMarshaller::get_int32( dods_int32 &val )
+{
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int32));
+    if (d_twiddle_bytes)
+        val = bswap_32(val);
+}
+
+void
+D4StreamUnMarshaller::get_int64( dods_int64 &val )
+{
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int64));
+    if (d_twiddle_bytes)
+        val = bswap_64(val);
+}
+
+void
+D4StreamUnMarshaller::get_float32( dods_float32 &val )
+{
+#if !USE_XDR_FOR_IEEE754_ENCODING
+	assert(std::numeric_limits<float>::is_iec559);
+
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float32));
+    if (d_twiddle_bytes) {
+        dods_int32 *i = reinterpret_cast<dods_int32*>(&val);
+        *i = bswap_32(*i);
+    }
+
+#else
+    if (std::numeric_limits<float>::is_iec559) {
+        d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float32));
+        if (d_twiddle_bytes) {
+            dods_int32 *i = reinterpret_cast<dods_int32*>(&val);
+            *i = bswap_32(*i);
+        }
+
+    }
+    else {
+        xdr_setpos( &d_source, 0);
+        d_in.read(d_buf, sizeof(dods_float32));
+
+        if (!xdr_float(&d_source, &val))
+            throw Error("Network I/O Error. Could not read float 64 data.");
+    }
+#endif
+}
+
+void
+D4StreamUnMarshaller::get_float64( dods_float64 &val )
+{
+#if !USE_XDR_FOR_IEEE754_ENCODING
+	assert(std::numeric_limits<double>::is_iec559);
+
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float64));
+    if (d_twiddle_bytes) {
+        dods_int64 *i = reinterpret_cast<dods_int64*>(&val);
+        *i = bswap_64(*i);
+    }
+
+#else
+    if (std::numeric_limits<float>::is_iec559) {
+        d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float64));
+        if (d_twiddle_bytes) {
+            dods_int64 *i = reinterpret_cast<dods_int64*>(&val);
+            *i = bswap_64(*i);
+        }
+    }
+    else {
+        xdr_setpos( &d_source, 0);
+        d_in.read(d_buf, sizeof(dods_float64));
+
+        if (!xdr_double(&d_source, &val))
+            throw Error("Network I/O Error. Could not read float 64 data.");
+    }
+#endif
+}
+
+void
+D4StreamUnMarshaller::get_uint16( dods_uint16 &val )
+{
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_uint16));
+    if (d_twiddle_bytes)
+        val = bswap_16(val);
+}
+
+void
+D4StreamUnMarshaller::get_uint32( dods_uint32 &val )
+{
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_uint32));
+    if (d_twiddle_bytes)
+        val = bswap_32(val);
+}
+
+void
+D4StreamUnMarshaller::get_uint64( dods_uint64 &val )
+{
+    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_uint64));
+    if (d_twiddle_bytes)
+        val = bswap_64(val);
+}
+
+void
+D4StreamUnMarshaller::get_str( string &val )
+{
+    int64_t len;
+    d_in.read(reinterpret_cast<char*>(&len), sizeof(int64_t));
+
+    val.resize(len);
+    d_in.read(&val[0], len);
+}
+
+void
+D4StreamUnMarshaller::get_url( string &val )
+{
+    get_str( val ) ;
+}
+
+/**
+ * Read a count value from the stream. This is used with D4Sequence
+ * which needs to use various other 'get' methods to read its fields.
+ * Methods like get_opaque_dap4() handle reading their count values
+ * themselves.
+ *
+ * @param count The number of elements to follow.
+ */
+int64_t
+D4StreamUnMarshaller::get_count()
+{
+	int64_t count;
+	d_in.read(reinterpret_cast<char*>(&count), sizeof(count));
+	return count;
+}
+
+/**
+ * Get opaque data when the size of the data to be read is not known in
+ * advance.
+ *
+ * @param val Value-result parameter for the data; caller must delete.
+ * @param len value-result parameter for the length of the data
+ */
+void
+D4StreamUnMarshaller::get_opaque_dap4( char **val, int64_t &len )
+{
+    //len = get_length_prefix();
+	d_in.read(reinterpret_cast<char*>(&len), sizeof(len));
+
+    *val = new char[len];
+    d_in.read(*val, len);
+}
+
+void
+D4StreamUnMarshaller::get_opaque_dap4( vector<uint8_t> &val )
+{
+    //len = get_length_prefix();
+	int64_t len;
+	d_in.read(reinterpret_cast<char*>(&len), sizeof(len));
+
+    val.resize(len);
+    d_in.read(reinterpret_cast<char*>(&val[0]), len);
+}
+
+void
+D4StreamUnMarshaller::get_vector( char *val, int64_t bytes )
+{
+    d_in.read(val, bytes);
+}
+
+#if USE_XDR_FOR_IEEE754_ENCODING
+void D4StreamUnMarshaller::m_deserialize_reals(char *val, int64_t num, int width, Type type)
+{
+    int64_t size = num * width;
+    // char *buf = (char*)malloc(size); jhrg 7/23/13
+    vector<char> buf(size);
+    XDR xdr;
+    xdrmem_create(&xdr, &buf[0], size, XDR_DECODE);
+    try {
+        xdr_setpos(&d_source, 0);
+        d_in.read(&buf[0], size);
+
+        if(!xdr_array(&xdr, &val, (unsigned int *)&num, size, width, XDRUtils::xdr_coder(type)))
+            throw InternalErr(__FILE__, __LINE__, "Error deserializing a Float64 array");
+
+        if (xdr_getpos(&xdr) != size)
+            throw InternalErr(__FILE__, __LINE__, "Error deserializing a Float64 array");
+    }
+    catch (...) {
+        xdr_destroy(&xdr);
+        throw;
+    }
+    xdr_destroy(&xdr);
+}
+#endif
+
+void D4StreamUnMarshaller::m_twidle_vector_elements(char *vals, int64_t num, int width)
+{
+    switch (width) {
+        case 2: {
+            dods_int16 *local = reinterpret_cast<dods_int16*>(vals);
+            while (num--) {
+                *local = bswap_16(*local);
+                local++;
+            }
+            break;
+        }
+        case 4: {
+            dods_int32 *local = reinterpret_cast<dods_int32*>(vals);;
+            while (num--) {
+                *local = bswap_32(*local);
+                local++;
+            }
+            break;
+        }
+        case 8: {
+            dods_int64 *local = reinterpret_cast<dods_int64*>(vals);;
+            while (num--) {
+                *local = bswap_64(*local);
+                local++;
+            }
+            break;
+        }
+        default:
+            throw InternalErr(__FILE__, __LINE__, "Unrecognized word size.");
+    }
+}
+
+void
+D4StreamUnMarshaller::get_vector(char *val, int64_t num_elem, int elem_size)
+{
+	assert(std::numeric_limits<float>::is_iec559);
+	assert(std::numeric_limits<double>::is_iec559);
+	assert(val);
+	assert(num_elem >= 0);
+	assert(elem_size > 0);
+
+	int64_t bytes;
+
+	switch (elem_size) {
+	case 1:
+		assert(!"Don't call this method for bytes, use put_vector(val, bytes) instead");
+		bytes = num_elem;
+		break;
+	case 2:
+		// Don't bother testing the sign bit
+		assert(!(num_elem & 0x4000000000000000)); // 0x 40 00 --> 0100 0000
+		bytes = num_elem << 1;
+		break;
+	case 4:
+		assert(!(num_elem & 0x6000000000000000)); // 0x 60 00 --> 0110 0000
+		bytes = num_elem << 2;
+		break;
+	case 8:
+		assert(!(num_elem & 0x7000000000000000)); // 0111 0000
+		bytes = num_elem << 3;
+		break;
+	default:
+		bytes = num_elem * elem_size;
+		break;
+	}
+
+    d_in.read(val, bytes);
+
+    if (d_twiddle_bytes)
+        m_twidle_vector_elements(val, num_elem, elem_size);
+}
+
+void
+D4StreamUnMarshaller::get_vector_float32(char *val, int64_t num_elem)
+{
+#if !USE_XDR_FOR_IEEE754_ENCODING
+	assert(std::numeric_limits<float>::is_iec559);
+	assert(val);
+	assert(num_elem >= 0);
+	assert(!(num_elem & 0x6000000000000000)); // 0x 60 00 --> 0110 0000
+
+	int64_t bytes = num_elem << 2;
+
+    d_in.read(val, bytes);
+
+    if (d_twiddle_bytes)
+        m_twidle_vector_elements(val, num_elem, sizeof(dods_float32));
+
+#else
+    if (type == dods_float32_c && !std::numeric_limits<float>::is_iec559) {
+        // If not using IEEE 754, use XDR to get it that way.
+        m_deserialize_reals(val, num, 4, type);
+    }
+    else if (type == dods_float64_c && !std::numeric_limits<double>::is_iec559) {
+        m_deserialize_reals(val, num, 8, type);
+    }
+    else {
+        d_in.read(val, num * width);
+        if (d_twiddle_bytes)
+            m_twidle_vector_elements(val, num, width);
+    }
+#endif
+}
+
+void
+D4StreamUnMarshaller::get_vector_float64(char *val, int64_t num_elem)
+{
+#if !USE_XDR_FOR_IEEE754_ENCODING
+	assert(std::numeric_limits<float>::is_iec559);
+	assert(val);
+	assert(num_elem >= 0);
+	assert(!(num_elem & 0x7000000000000000)); // 0x 70 00 --> 0111 0000
+
+	int64_t bytes = num_elem << 3;
+
+    d_in.read(val, bytes);
+
+    if (d_twiddle_bytes)
+        m_twidle_vector_elements(val, num_elem, sizeof(dods_float64));
+
+#else
+    if (type == dods_float32_c && !std::numeric_limits<float>::is_iec559) {
+        // If not using IEEE 754, use XDR to get it that way.
+        m_deserialize_reals(val, num, 4, type);
+    }
+    else if (type == dods_float64_c && !std::numeric_limits<double>::is_iec559) {
+        m_deserialize_reals(val, num, 8, type);
+    }
+    else {
+        d_in.read(val, num * width);
+        if (d_twiddle_bytes)
+            m_twidle_vector_elements(val, num, width);
+    }
+#endif
+}
+
+void
+D4StreamUnMarshaller::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "D4StreamUnMarshaller::dump - ("
+         << (void *)this << ")" << endl ;
+}
+
+} // namespace libdap
+
diff --git a/DAP4StreamUnMarshaller.h b/D4StreamUnMarshaller.h
similarity index 55%
rename from DAP4StreamUnMarshaller.h
rename to D4StreamUnMarshaller.h
index f535069..f21d01f 100644
--- a/DAP4StreamUnMarshaller.h
+++ b/D4StreamUnMarshaller.h
@@ -1,4 +1,4 @@
-// DAP4StreamUnMarshaller.h
+// D4StreamUnMarshaller.h
 
 // -*- mode: c++; c-basic-offset:4 -*-
 
@@ -20,74 +20,79 @@
 //
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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 I_DAP4StreamUnMarshaller_h
-#define I_DAP4StreamUnMarshaller_h 1
+#ifndef I_D4StreamUnMarshaller_h
+#define I_D4StreamUnMarshaller_h 1
 
 #include <iostream>
 
-using std::istream ;
-using std::cin ;
+// See comment in D4StreamMarshaller
+#define USE_XDR_FOR_IEEE754_ENCODING 0
+
+#if USE_XDR_FOR_IEEE754_ENCODING
+#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
+#endif
 
+#include <crc.h>
+
+// #include "Type.h"
+#include "dods-datatypes.h"
 #include "UnMarshaller.h"
-#include "BaseType.h"
-#include "XDRUtils.h"
+#include "InternalErr.h"
+
+#include "debug.h"
 
-namespace libdap
-{
+using std::istream;
+
+namespace libdap {
 
 class Vector;
 
-/** @brief Read data from the stream made by DAP4StreamMarshaller.
+/** @brief Read data from the stream made by D4StreamMarshaller.
  */
-class DAP4StreamUnMarshaller: public UnMarshaller {
+class D4StreamUnMarshaller: public UnMarshaller {
 public:
-    const static unsigned int c_md5_length = 16;
+    const static unsigned int c_checksum_length = 4;
 
 private:
     istream &d_in;
     bool d_twiddle_bytes;
 
+#if USE_XDR_FOR_IEEE754_ENCODING
     // These are used for reals that need to be converted from IEEE 754
     XDR d_source;
-    dods_float64 d_buf;
-
-    DAP4StreamUnMarshaller();
-#if 0
-    : d_in(cin) {
-        throw InternalErr( __FILE__, __LINE__, "not implemented." ) ;
-    }
-#endif
-    DAP4StreamUnMarshaller(const DAP4StreamUnMarshaller &);
-#if 0
-    : UnMarshaller(), d_in(cin) {
-        throw InternalErr( __FILE__, __LINE__, "not implemented." ) ;
-    }
+    char d_buf[sizeof(dods_float64)];
 #endif
 
-    DAP4StreamUnMarshaller & operator=(const DAP4StreamUnMarshaller &);
-#if 0
-    {
-        throw InternalErr( __FILE__, __LINE__, "not implemented." ) ;
-    }
+    D4StreamUnMarshaller();
+    D4StreamUnMarshaller(const D4StreamUnMarshaller &);
+    D4StreamUnMarshaller & operator=(const D4StreamUnMarshaller &);
+#if USE_XDR_FOR_IEEE754_ENCODING
+    void m_deserialize_reals(char *val, int64_t num, int width, Type type);
 #endif
-
-    void m_deserialize_reals(char *val, unsigned int num, int width, Type type);
-    void m_twidle_vector_elements(char *vals, unsigned int num, int width);
+    void m_twidle_vector_elements(char *vals, int64_t num, int width);
 
 public:
-    struct checksum {
-        unsigned char md[c_md5_length];
-    };
+    D4StreamUnMarshaller(istream &in, bool twiddle_bytes);
+    D4StreamUnMarshaller(istream &in);
+    virtual ~D4StreamUnMarshaller();
 
-    DAP4StreamUnMarshaller(istream &in, bool is_stream_bigendian);
-    virtual ~DAP4StreamUnMarshaller();
+    void set_twiddle_bytes(bool twiddle) { d_twiddle_bytes = twiddle; }
 
-    checksum get_checksum();
-    string get_checksum(checksum c);
+    Crc32::checksum get_checksum();
+    string get_checksum_str();
+    int64_t get_count();
 
     virtual void get_byte(dods_byte &val);
     virtual void get_int8(dods_int8 &val);
@@ -108,15 +113,17 @@ public:
     virtual void get_str(string &val);
     virtual void get_url(string &val);
 
-    virtual void get_opaque(char *val, unsigned int len);
-    virtual void get_opaque(char **val, unsigned int &len);
+    virtual void get_opaque(char *, unsigned int) {
+    	throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4, use get_opaque_dap4() instead.");
+    }
+
+    virtual void get_opaque_dap4(char **val, int64_t &len);
+    virtual void get_opaque_dap4( vector<uint8_t> &val );
 
     virtual void get_int(int &) {
         throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4");
     }
 
-    virtual dods_uint64 get_length_prefix();
-
     // Note that DAP4 assumes clients know the size of arrays when they
     // read the data; it's the 'varying' get methods that read & return the
     // number of elements. These methods are here to appease the UnMarshaller
@@ -129,16 +136,15 @@ public:
         throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4");
     }
 
-    virtual void get_vector(char *val, unsigned int num);
-    virtual void get_vector(char *val, unsigned int num, int width, Type type);
-
-    virtual void get_varying_vector(char **val, unsigned int &num);
-    virtual void get_varying_vector(char **val, unsigned int &num, int width, Type type);
+    virtual void get_vector(char *val, int64_t num_bytes);
+    virtual void get_vector(char *val, int64_t num_elem, int elem_size);
+    virtual void get_vector_float32(char *val, int64_t num_elem);
+    virtual void get_vector_float64(char *val, int64_t num_elem);
 
     virtual void dump(ostream &strm) const;
 };
 
 } // namespace libdap
 
-#endif // I_DAP4StreamUnMarshaller_h
+#endif // I_D4StreamUnMarshaller_h
 
diff --git a/DAP4StreamUnMarshaller.cc b/DAP4StreamUnMarshaller.cc
deleted file mode 100644
index 684c39d..0000000
--- a/DAP4StreamUnMarshaller.cc
+++ /dev/null
@@ -1,412 +0,0 @@
-// DAP4StreamUnMarshaller.cc
-
-// -*- mode: c++; c-basic-offset:4 -*-
-
-// This file is part of libdap, A C++ implementation of the OPeNDAP Data
-// Access Protocol.
-
-// Copyright (c) 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
-
-#include "config.h"
-#include "DAP4StreamUnMarshaller.h"
-
-#include <byteswap.h>
-
-#include <iostream>
-#include <iomanip>
-
-#include <string>
-#include <sstream>
-
-//#define DODS_DEBUG2 1
-//#define DODS_DEBUG 1
-
-#include "util.h"
-#include "XDRUtils.h"
-#include "InternalErr.h"
-#include "debug.h"
-
-namespace libdap {
-
-static inline bool is_host_big_endian()
-{
-#ifdef COMPUTE_ENDIAN_AT_RUNTIME
-
-    dods_int16 i = 0x0100;
-    char *c = reinterpret_cast<char*>(&i);
-    return *c;
-
-#else
-
-#ifdef WORDS_BIGENDIAN
-    return true;
-#else
-    return false;
-#endif
-
-#endif
-}
-
-DAP4StreamUnMarshaller::DAP4StreamUnMarshaller(istream &in, bool is_stream_big_endian)
-    : d_in( in ), d_buf(0)
-{
-#if 0
-	// XDR is used to handle transforming non-ieee754 reals, nothing else.
-    if (!d_buf)
-    	// Leaked??? See the XDRStream code
-        d_buf = (char *) malloc(sizeof(dods_float64));
-    if (!d_buf)
-        throw Error("Failed to allocate memory for data serialization.");
-#endif
-
-    xdrmem_create(&d_source, &d_buf, sizeof(dods_float64), XDR_DECODE);
-
-    // This will cause exceptions to be thrown on i/o errors. The exception
-    // will be ostream::failure
-    d_in.exceptions(istream::failbit | istream::badbit);
-
-    DBG(cerr << "Host is big endian: " << is_host_big_endian() << endl);
-
-    if ((is_host_big_endian() && is_stream_big_endian)
-        || (!is_host_big_endian() && !is_stream_big_endian))
-        d_twiddle_bytes = false;
-    else
-        d_twiddle_bytes = true;
-}
-
-DAP4StreamUnMarshaller::~DAP4StreamUnMarshaller( )
-{
-}
-
-DAP4StreamUnMarshaller::checksum DAP4StreamUnMarshaller::get_checksum()
-{
-    checksum c;
-    d_in.read(reinterpret_cast<char*>(&c), c_md5_length);
-
-    return c;
-}
-
-string DAP4StreamUnMarshaller::get_checksum(DAP4StreamUnMarshaller::checksum c)
-{
-    unsigned char *md = reinterpret_cast<unsigned char*>(&c);
-
-    ostringstream oss;
-    oss.setf(ios::hex, ios::basefield);
-    for (unsigned int i = 0; i < c_md5_length; ++i) {
-        oss << setfill('0') << setw(2) << (unsigned int)md[i];
-    }
-
-    return oss.str();
-}
-
-void
-DAP4StreamUnMarshaller::get_byte( dods_byte &val )
-{
-    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_byte));
-}
-
-void
-DAP4StreamUnMarshaller::get_int8( dods_int8 &val )
-{
-    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int8));
-}
-
-void
-DAP4StreamUnMarshaller::get_int16( dods_int16 &val )
-{
-    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int16));
-    if (d_twiddle_bytes)
-        val = bswap_16(val);
-}
-
-void
-DAP4StreamUnMarshaller::get_int32( dods_int32 &val )
-{
-    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int32));
-    if (d_twiddle_bytes)
-        val = bswap_32(val);
-}
-
-void
-DAP4StreamUnMarshaller::get_int64( dods_int64 &val )
-{
-    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int64));
-    if (d_twiddle_bytes)
-        val = bswap_64(val);
-}
-
-void
-DAP4StreamUnMarshaller::get_float32( dods_float32 &val )
-{
-    if (std::numeric_limits<float>::is_iec559) {
-        d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float32));
-        if (d_twiddle_bytes) {
-            dods_int32 *i = reinterpret_cast<dods_int32*>(&val);
-            *i = bswap_32(*i);
-        }
-
-    }
-    else {
-        xdr_setpos( &d_source, 0);
-        d_in.read(d_buf, sizeof(dods_float32));
-
-        if (!xdr_float(&d_source, &val))
-            throw Error("Network I/O Error. Could not read float 64 data.");
-    }
-}
-
-void
-DAP4StreamUnMarshaller::get_float64( dods_float64 &val )
-{
-    if (std::numeric_limits<float>::is_iec559) {
-        d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float64));
-        if (d_twiddle_bytes) {
-            dods_int64 *i = reinterpret_cast<dods_int64*>(&val);
-            *i = bswap_32(*i);
-        }
-    }
-    else {
-        xdr_setpos( &d_source, 0);
-        d_in.read(d_buf, sizeof(dods_float64));
-
-        if (!xdr_double(&d_source, &val))
-            throw Error("Network I/O Error. Could not read float 64 data.");
-    }
-}
-
-void
-DAP4StreamUnMarshaller::get_uint16( dods_uint16 &val )
-{
-    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_uint16));
-    if (d_twiddle_bytes)
-        val = bswap_16(val);
-}
-
-void
-DAP4StreamUnMarshaller::get_uint32( dods_uint32 &val )
-{
-    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_uint32));
-    if (d_twiddle_bytes)
-        val = bswap_32(val);
-}
-
-void
-DAP4StreamUnMarshaller::get_uint64( dods_uint64 &val )
-{
-    d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_uint64));
-    if (d_twiddle_bytes)
-        val = bswap_64(val);
-}
-
-/**
- * Read a varint (128-bit varying integer). Not the most optimized version
- * possible. It would be better if the values were in memory and we could
- * operate on them without a separate read for each byte.
- */
-dods_uint64 DAP4StreamUnMarshaller::get_length_prefix()
-{
-    uint8_t b;
-    int count = 0;
-    dods_uint64 result = 0;
-    do {
-        d_in.read(reinterpret_cast<char*>(&b), 1);
-
-        uint64_t v = (b & 0x7f) << 7 * count;
-        result += v; // is v needed? Does it matter?
-        count++;
-
-    } while (b & 0x80);
-
-    return result;
-}
-
-
-void
-DAP4StreamUnMarshaller::get_str( string &val )
-{
-    dods_int64 len = get_length_prefix();
-    vector<char> raw(len+1);
-    d_in.read(&raw[0], len);
-
-    val.reserve(len);
-    val.assign(&raw[0], len);
-}
-
-void
-DAP4StreamUnMarshaller::get_url( string &val )
-{
-    get_str( val ) ;
-}
-
-/**
- * Get opaque data when the size of the data to read is known.
- *
- * @param val Pointer to 'len' bytes; store the data here.
- * @param len Number of bytes referenced adn expected
- * @exception Error if the number of bytes indicated in the stream does not
- * match 'len'
- */
-void
-DAP4StreamUnMarshaller::get_opaque( char *val, unsigned int len )
-{
-    dods_int64 rlen = get_length_prefix();
-    if (len != rlen)
-        throw Error("Expected opaque data of " + long_to_string(len)
-                + " bytes, but got " + long_to_string(rlen) + " instead.");
-
-    d_in.read(val, len);
-}
-
-/**
- * Get opaque data when the size of the data to be read is not known in
- * advance.
- *
- * @param val Value-result parameter for the data; caller must delete.
- * @param len value-result parameter for the length of the data
- */
-void
-DAP4StreamUnMarshaller::get_opaque( char **val, unsigned int &len )
-{
-    len = get_length_prefix();
-
-    *val = new char[len];
-    d_in.read(*val, len);
-}
-
-void
-DAP4StreamUnMarshaller::get_vector( char *val, unsigned int num )
-{
-    d_in.read(val, num);
-}
-
-/**
- * @todo recode this so that it does not copy data to a new buffer but
- * serializes directly to the stream (element by element) and compare the
- * run times.
- */
-void DAP4StreamUnMarshaller::m_deserialize_reals(char *val, unsigned int num, int width, Type type)
-{
-    dods_uint64 size = num * width;
-    //char *buf = (char*)malloc(size); This was leaked; xdr_destroy() does not free it.
-    vector<char> buf(size);
-    XDR xdr;
-    xdrmem_create(&xdr, &buf[0], size, XDR_DECODE);
-    try {
-        xdr_setpos(&d_source, 0);
-        d_in.read(&buf[0], size);
-
-        if(!xdr_array(&xdr, &val, (unsigned int *)&num, size, width, XDRUtils::xdr_coder(type)))
-            throw InternalErr(__FILE__, __LINE__, "Error deserializing a Float64 array");
-
-        if (xdr_getpos(&xdr) != size)
-            throw InternalErr(__FILE__, __LINE__, "Error deserializing a Float64 array");
-    }
-    catch (...) {
-        xdr_destroy(&xdr);
-        throw;
-    }
-    xdr_destroy(&xdr);
-}
-
-void DAP4StreamUnMarshaller::m_twidle_vector_elements(char *vals, unsigned int num, int width)
-{
-    switch (width) {
-        case 2: {
-            dods_int16 *local = reinterpret_cast<dods_int16*>(vals);
-            while (num--) {
-                *local = bswap_16(*local);
-                local++;
-            }
-            break;
-        }
-        case 4: {
-            dods_int32 *local = reinterpret_cast<dods_int32*>(vals);;
-            while (num--) {
-                *local = bswap_32(*local);
-                local++;
-            }
-            break;
-        }
-        case 8: {
-            dods_int64 *local = reinterpret_cast<dods_int64*>(vals);;
-            while (num--) {
-                *local = bswap_64(*local);
-                local++;
-            }
-            break;
-        }
-        default:
-            throw InternalErr(__FILE__, __LINE__, "Unrecognized word size.");
-    }
-}
-
-void
-DAP4StreamUnMarshaller::get_vector( char *val, unsigned int num, int width, Type type )
-{
-    if (type == dods_float32_c && !std::numeric_limits<float>::is_iec559) {
-        // If not using IEEE 754, use XDR to get it that way.
-        m_deserialize_reals(val, num, 4, type);
-    }
-    else if (type == dods_float64_c && !std::numeric_limits<double>::is_iec559) {
-        m_deserialize_reals(val, num, 8, type);
-    }
-    else {
-        d_in.read(val, num * width);
-        if (d_twiddle_bytes)
-            m_twidle_vector_elements(val, num, width);
-    }
-}
-
-void
-DAP4StreamUnMarshaller::get_varying_vector( char **val, unsigned int &num )
-{
-    get_opaque(val, num);
-}
-
-void
-DAP4StreamUnMarshaller::get_varying_vector( char **val, unsigned int &num, int width, Type type )
-{
-    num = get_length_prefix();
-
-    int size = num * width;
-    *val = new char[size];
-
-    if (type == dods_float32_c && !std::numeric_limits<float>::is_iec559) {
-        m_deserialize_reals(*val, num, 4, type);
-    }
-    else if (type == dods_float64_c && !std::numeric_limits<double>::is_iec559) {
-        m_deserialize_reals(*val, num, 8, type);
-    }
-    else {
-        d_in.read(*val, size);
-        if (d_twiddle_bytes)
-            m_twidle_vector_elements(*val, num, width);
-    }
-}
-
-void
-DAP4StreamUnMarshaller::dump(ostream &strm) const
-{
-    strm << DapIndent::LMarg << "DAP4StreamUnMarshaller::dump - ("
-         << (void *)this << ")" << endl ;
-}
-
-} // namespace libdap
-
diff --git a/DDS.cc b/DDS.cc
index 7284f9e..b7f3cf3 100644
--- a/DDS.cc
+++ b/DDS.cc
@@ -82,6 +82,16 @@
 
 #include "escaping.h"
 
+/**
+ * ############################################################################################
+ * ############################################################################################
+ * ############################################################################################
+ * DapXmlNamespaces
+ *
+ * FIXME Replace all usages of the following variable with calls to DapXmlNamespaces
+ * TODO  Replace all usages of the following variable with calls to DapXmlNamespaces
+ *
+ */
 const string c_xml_xsi = "http://www.w3.org/2001/XMLSchema-instance";
 const string c_xml_namespace = "http://www.w3.org/XML/1998/namespace";
 
@@ -98,6 +108,15 @@ const string c_dap40_namespace = "http://xml.opendap.org/ns/DAP/4.0#";
 const string c_dap_20_n_sl = c_dap20_namespace + " " + c_default_dap20_schema_location;
 const string c_dap_32_n_sl = c_dap32_namespace + " " + c_default_dap32_schema_location;
 const string c_dap_40_n_sl = c_dap40_namespace + " " + c_default_dap40_schema_location;
+/**
+ *
+ * DapXmlNamespaces
+ * ############################################################################################
+ * ############################################################################################
+ * ############################################################################################
+ */
+
+
 
 using namespace std;
 
@@ -266,51 +285,64 @@ DDS::operator=(const DDS &rhs)
  *
  * @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()) {
-		try {
-			DBG(cerr << "Processing the attributes for: " << (*var)->d_name() << " a " << (*var)->type_name() << endl);
-			(*var)->transfer_attributes(top_level);
-			var++;
-		} catch (Error &e) {
-			DBG(cerr << "Got this exception: " << e.get_error_message() << endl);
-			var++;
-			throw e;
-		}
-	}
+void DDS::transfer_attributes(DAS *das)
+{
+    // If there is a container set in the DDS then check 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 && 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 = das->get_top_level_attributes();
+
+    for (DDS::Vars_iter i = var_begin(), e = var_end(); i != e; i++) {
+        (*i)->transfer_attributes(top);
+    }
+#if 0
+    Vars_iter var = var_begin();
+    while (var != var_end()) {
+        try {
+            DBG(cerr << "Processing the attributes for: " << (*var)->d_name() << " a " << (*var)->type_name() << endl);
+            (*var)->transfer_attributes(top);
+            var++;
+        }
+        catch (Error &e) {
+            DBG(cerr << "Got this exception: " << e.get_error_message() << endl);
+            var++;
+            throw e;
+        }
+    }
+#endif
+    // Now we transfer all of the attributes still marked as global to the
+    // global container in the DDS.
+    for (AttrTable::Attr_iter i = top->attr_begin(), e = top->attr_end(); i != e; ++i) {
+        if ((*i)->type == Attr_container && (*i)->attributes->is_global_attribute()) {
+            // copy the source container so that the DAS passed in can be
+            // deleted after calling this method.
+            AttrTable *at = new AttrTable(*(*i)->attributes);
+            d_attr.append_container(at, at->get_name());
+        }
+    }
+#if 0
+    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)->d_name << " is a global attribute." << endl);
+            // copy the source container so that the DAS passed in can be
+            // deleted after calling this method.
+            AttrTable *at = new AttrTable(*(*at_cont_p)->attributes);
+            d_attr.append_container(at, at->get_name());
+        }
 
-	// 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)->d_name << " is a global attribute." << endl);
-			// copy the source container so that the DAS passed in can be
-			// deleted after calling this method.
-			AttrTable *at = new AttrTable(*(*at_cont_p)->attributes);
-			d_attr.append_container(at, at->get_name());
-		}
-
-		at_cont_p++;
-	}
+        at_cont_p++;
+    }
+#endif
 }
 
 /** Get and set the dataset's d_name.  This is the d_name of the dataset
@@ -354,7 +386,7 @@ DDS::get_attr_table()
 //@{
 /** Gets the dataset file d_name. */
 string
-DDS::filename()
+DDS::filename() const
 {
     return d_filename;
 }
diff --git a/DDS.h b/DDS.h
index d9d45ca..778ddf8 100644
--- a/DDS.h
+++ b/DDS.h
@@ -256,7 +256,7 @@ public:
 
     virtual AttrTable &get_attr_table();
 
-    string filename();
+    string filename() const;
     void filename(const string &fn);
 
     /// Get the DAP major version as sent by the client
@@ -316,10 +316,18 @@ public:
 
     /// Return an iterator to the first variable
     Vars_iter var_begin();
+#if 0
+    /// Return a const iterator.
+    Vars_citer var_cbegin() const { return vars.cbegin(); }
+#endif
     /// Return a reverse iterator
     Vars_riter var_rbegin();
     /// Return an iterator
     Vars_iter var_end();
+#if 0
+    /// Return a const iterator
+    Vars_citer var_cend() const { return vars.cend(); }
+#endif
     /// Return a reverse iterator
     Vars_riter var_rend();
     /// Get an iterator
diff --git a/DDXParserSAX2.cc b/DDXParserSAX2.cc
index 96b8902..d2d88e3 100644
--- a/DDXParserSAX2.cc
+++ b/DDXParserSAX2.cc
@@ -363,6 +363,7 @@ void DDXParser::process_variable(Type t, ParseState s, const xmlChar **attrs,
     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);
@@ -489,6 +490,7 @@ void DDXParser::finish_variable(const char *tag, Type t, const char *expected)
         DDXParser::ddx_fatal_error(this,
                                    "Internal error: Expected a %s variable.",
                                    expected);
+        delete btp;
         return;
     }
     // Once libxml2 validates, this can go away. 05/30/03 jhrg
@@ -513,8 +515,7 @@ void DDXParser::finish_variable(const char *tag, Type t, const char *expected)
         return;
     }
 
-    parent->add_var(btp);
-    delete btp;
+    parent->add_var_nocopy(btp);
 }
 
 /** @name SAX Parser Callbacks
@@ -561,7 +562,6 @@ void DDXParser::ddx_end_document(void * p)
     // 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) {
-    	delete parser->bt_stack.top();
         return;
     }
 
@@ -569,8 +569,9 @@ void DDXParser::ddx_end_document(void * p)
     // to the DDS.
     Constructor *cp = dynamic_cast < Constructor * >(parser->bt_stack.top());
     if (!cp) {
+        delete parser->bt_stack.top();
+        parser->bt_stack.pop();
     	ddx_fatal_error(parser, "Parse error: Expected a Structure, Sequence or Grid variable.");
-    	delete cp;
 		return;
     }
 
@@ -579,8 +580,8 @@ void DDXParser::ddx_end_document(void * p)
         parser->dds->add_var(*i);
     }
 
+    delete parser->bt_stack.top();
     parser->bt_stack.pop();
-    delete cp;
 }
 
 void DDXParser::ddx_sax2_start_element(void *p,
@@ -925,7 +926,7 @@ void DDXParser::ddx_sax2_end_element(void *p, const xmlChar *l,
                 parent->add_var(btp);
                 delete btp;
             }
-            else
+            else {
                 DDXParser::ddx_fatal_error(parser,
                                            "Tried to add the simple-type variable '%s' to a non-constructor type (%s %s).",
                                            localname,
@@ -933,11 +934,14 @@ void DDXParser::ddx_sax2_end_element(void *p, const xmlChar *l,
                                            type_name().c_str(),
                                            parser->bt_stack.top()->name().
                                            c_str());
+                delete btp;
+            }
         }
-        else
+        else {
             DDXParser::ddx_fatal_error(parser,
                                        "Expected an end tag for a simple type; found '%s' instead.",
                                        localname);
+        }
         break;
     }
 
@@ -1094,33 +1098,32 @@ void DDXParser::ddx_fatal_error(void * p, const char *msg, ...)
 
 //@}
 
-void DDXParser::cleanup_parse(xmlParserCtxtPtr & context) const
+void DDXParser::cleanup_parse(xmlParserCtxtPtr & context)
 {
-    if (!context->wellFormed) {
-        context->sax = NULL;
-        xmlFreeParserCtxt(context);
-        throw
-        DDXParseFailed(string
-                       ("\nThe DDX is not a well formed XML document.\n")
-                       + error_msg);
+    bool wellFormed = context->wellFormed;
+    bool valid = context->valid;
+
+    context->sax = NULL;
+    xmlFreeParserCtxt(context);
+
+    // If there's an error, there may still be items on the stack at the
+    // end of the parse.
+    while (!bt_stack.empty()) {
+        delete bt_stack.top();
+        bt_stack.pop();
     }
 
-    if (!context->valid) {
-        context->sax = NULL;
-        xmlFreeParserCtxt(context);
-        throw DDXParseFailed(string("\nThe DDX is not a valid document.\n")
-                             + error_msg);
+    if (!wellFormed) {
+        throw DDXParseFailed(string("\nThe DDX is not a well formed XML document.\n") + error_msg);
     }
 
-    if (get_state() == parser_error) {
-        context->sax = NULL;
-        xmlFreeParserCtxt(context);
-        throw DDXParseFailed(string("\nError parsing DDX response.\n") +
-                             error_msg);
+    if (!valid) {
+        throw DDXParseFailed(string("\nThe DDX is not a valid document.\n") + error_msg);
     }
 
-    context->sax = NULL;
-    xmlFreeParserCtxt(context);
+    if (get_state() == parser_error) {
+        throw DDXParseFailed(string("\nError parsing DDX response.\n") + error_msg);
+    }
 }
 
 /** Read a DDX from a C++ input stream and populate a DDS object.
diff --git a/DDXParserSAX2.h b/DDXParserSAX2.h
index 5a6d9b4..29e8199 100644
--- a/DDXParserSAX2.h
+++ b/DDXParserSAX2.h
@@ -195,7 +195,7 @@ private:
     BaseType *factory(Type t, const string &name);
 
     // Common cleanup code for intern() and intern_stream()
-    void cleanup_parse(xmlParserCtxtPtr &context) const;
+    void cleanup_parse(xmlParserCtxtPtr &context);
 
     /** @name Parser Actions
 
diff --git a/DMR.cc b/DMR.cc
new file mode 100644
index 0000000..1310562
--- /dev/null
+++ b/DMR.cc
@@ -0,0 +1,381 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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"
+
+#ifdef WIN32
+#include <io.h>
+#include <process.h>
+#include <fstream>
+#else
+#include <unistd.h>    // for alarm and dup
+#include <sys/wait.h>
+#endif
+
+#include <cassert>
+
+#include <iostream>
+#include <sstream>
+
+//#define DODS_DEBUG
+//#define DODS_DEBUG2
+
+#include "D4Group.h"
+#include "BaseType.h"
+#include "Array.h"
+#include "DMR.h"
+#include "XMLWriter.h"
+#include "D4BaseTypeFactory.h"
+#include "D4Attributes.h"
+
+#include "DDS.h"	// Included so DMRs can be built using a DDS for 'legacy' handlers
+
+#include "debug.h"
+
+
+/**
+ * DapXmlNamespaces
+ *
+ * TODO  Replace all uses of the following variable with calls to DapXmlNamespaces
+ */
+const string c_xml_xsi = "http://www.w3.org/2001/XMLSchema-instance";
+const string c_xml_namespace = "http://www.w3.org/XML/1998/namespace";
+
+const string c_default_dap40_schema_location = "http://xml.opendap.org/dap/dap4.0.xsd";
+
+const string c_dap40_namespace = "http://xml.opendap.org/ns/DAP/4.0#";
+
+const string c_dap_40_n_sl = c_dap40_namespace + " " + c_default_dap40_schema_location;
+
+using namespace std;
+
+namespace libdap {
+
+void
+DMR::m_duplicate(const DMR &dmr)
+{
+    // This is needed because we use the factory to make a new instance of the root group
+    assert(dmr.OK());
+
+    d_factory = dmr.d_factory; // Shallow copy here
+
+    d_name = dmr.d_name;
+    d_filename = dmr.d_filename;
+
+    d_dap_major = dmr.d_dap_major;
+    d_dap_minor = dmr.d_dap_minor;
+    d_dap_version = dmr.d_dap_version;       // String version of the protocol
+
+    d_dmr_version = dmr.d_dmr_version;
+
+    d_request_xml_base = dmr.d_request_xml_base;
+
+    d_namespace = dmr.d_namespace;
+
+    d_max_response_size = dmr.d_max_response_size;
+
+    // Deep copy, using ptr_duplicate()
+    d_root = dmr.d_root->ptr_duplicate();
+    DBG(cerr << "dmr.d_root: " << dmr.d_root << endl);
+    DBG(cerr << "d_root (from ptr_dup(): " << d_root << endl);
+
+    //d_root = static_cast<D4Group*>(dmr.d_factory->NewVariable(dods_group_c, dmr.d_root->name()));
+}
+
+/**
+ * Make a DMR which uses the given BaseTypeFactory to create variables.
+ *
+ * @note The default DAP version is 4.0 - use the DDS class to make DAP2
+ * things. The default DMR version is 1.0
+ *
+ * @param factory The D4BaseTypeFactory to use when creating instances of
+ * DAP4 variables. The caller must ensure the factory's lifetime is at least
+ * that of the DMR instance.
+ * @param name The name of the DMR - usually derived from the name of the
+ * pathname or table name of the dataset.
+ */
+DMR::DMR(D4BaseTypeFactory *factory, const string &name)
+        : d_factory(factory), d_name(name), d_filename(""),
+          d_dap_major(4), d_dap_minor(0),
+          d_dmr_version("1.0"), d_request_xml_base(""),
+          d_namespace(c_dap40_namespace), d_max_response_size(0), d_root(0)
+{
+    // sets d_dap_version string and the two integer fields too
+    set_dap_version("4.0");
+}
+
+/** @brief Build a DMR using a DAP2 DDS.
+ *
+ * Given a DDS from code written for DAP2, build a DAP4 DMR object. This
+ * works because DAP4 subsumes DAP2, but there are a few quirks... For
+ * each variable in the DDS, transform it to the equivalent DAP4 variable
+ * type and then copy the variable's attributes. Most types convert easily.
+ * Types that need special treatment are:
+ * Array: DAP2 array dimensions must be morphed to DAP4
+ * Sequence: Make a D4Sequence
+ * Grid: Make a coverage; assume Grids with the same dimension names
+ * have 'shared dimensions' and that maps with the same names are shared too.
+ *
+ * @note Assume that a DDS has only a root group. This is not actually
+ * true for a DDS from the HDF5 handler, because it has Groups encoded
+ * into the variable names. jhrg 3/18/14
+ *
+ * @param factory Factory class used to make new variables
+ * @param dds Get the variables to convert from this DAP2 DDS.
+ * @see BaseType::transform_to_dap4()
+ */
+DMR::DMR(D4BaseTypeFactory *factory, DDS &dds)
+        : d_factory(factory), d_name(dds.get_dataset_name()),
+          d_filename(dds.filename()), d_dap_major(4), d_dap_minor(0),
+          d_dmr_version("1.0"), d_request_xml_base(""),
+          d_namespace(c_dap40_namespace), d_max_response_size(0), d_root(0)
+{
+    // sets d_dap_version string and the two integer fields too
+    set_dap_version("4.0");
+
+    build_using_dds(dds);
+#if 0
+    for (DDS::Vars_iter i = dds.var_begin(), e = dds.var_end(); i != e; ++i) {
+    	BaseType *new_var = (*i)->transform_to_dap4(root() /*group*/, root() /*container*/);
+    	// If the variable being transformed is a Grid,
+    	// then Grid::transform_to_dap4() will add all the arrays to the
+    	// container (root() in this case) and return null, indicating that
+    	// this code does not need to do anything to add the transformed variable.
+    	if (new_var)
+    		root()->add_var_nocopy(new_var);
+    }
+
+    // Now copy the global attributes
+    root()->attributes()->transform_to_dap4(dds.get_attr_table());
+#endif
+}
+
+/**
+ * Make a DMR which uses the given BaseTypeFactory to create variables.
+ *
+ * @note The default DAP version is 4.0 - use the DDS class to make DAP2
+ * things. The default DMR version is 1.0
+ */
+DMR::DMR()
+        : d_factory(0), d_name(""), d_filename(""), d_dap_major(4), d_dap_minor(0),
+          d_dap_version("4.0"), d_dmr_version("1.0"), d_request_xml_base(""),
+          d_namespace(c_dap40_namespace), d_max_response_size(0), d_root(0)
+{
+    // sets d_dap_version string and the two integer fields too
+    set_dap_version("4.0");
+}
+
+/** The DMR copy constructor. */
+DMR::DMR(const DMR &rhs) : DapObj()
+{
+    m_duplicate(rhs);
+}
+
+/** Delete a DMR. The BaseType factory is not freed, while the contained
+ * group is.
+ */
+DMR::~DMR()
+{
+#if 1
+    delete d_root;
+#endif
+}
+
+DMR &
+DMR::operator=(const DMR &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    m_duplicate(rhs);
+
+    return *this;
+}
+
+/**
+ * If we have a DDS that includes Attributes, use it to build the DMR. This
+ * will copy all of the variables in the DDS into the DMR using BaseType::transform_to_dap4(),
+ * so the actual types added can be controlled by code that specializes
+ * the various type classes.
+ *
+ * @param dds Read variables and Attributes from this DDS
+ */
+void DMR::build_using_dds(DDS &dds)
+{
+	set_name(dds.get_dataset_name());
+	set_filename(dds.filename());
+
+	for (DDS::Vars_iter i = dds.var_begin(), e = dds.var_end(); i != e; ++i) {
+		BaseType *new_var = (*i)->transform_to_dap4(root() /*group*/, root() /*container*/);
+		// If the variable being transformed is a Grid,
+		// then Grid::transform_to_dap4() will add all the arrays to the
+		// container (root() in this case) and return null, indicating that
+		// this code does not need to do anything to add the transformed variable.
+		if (new_var) root()->add_var_nocopy(new_var);
+	}
+
+	// Now copy the global attributes
+	root()->attributes()->transform_to_dap4(dds.get_attr_table());
+}
+
+D4Group *
+DMR::root()
+{
+	if (!d_root) d_root = static_cast<D4Group*>(d_factory->NewVariable(dods_group_c, "/"));
+	return d_root;
+}
+
+/**
+ * Given the DAP protocol version, parse that string and set the DMR fields.
+ *
+ * @param v The version string.
+ */
+void
+DMR::set_dap_version(const string &v)
+{
+    istringstream iss(v);
+
+    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;
+
+    if (major == -1 || minor == -1 or dot != '.')
+        throw InternalErr(__FILE__, __LINE__, "Could not parse dap version. Value given: " + v);
+
+    d_dap_version = v;
+
+    d_dap_major = major;
+    d_dap_minor = minor;
+
+    // Now set the related XML constants. These might be overwritten if
+    // the DMR instance is being built from a document parse, but if it's
+    // being constructed by a server the code to generate the XML document
+    // needs these values to match the DAP version information.
+    switch (d_dap_major) {
+        case 4:
+            d_namespace = c_dap40_namespace;
+            break;
+        default:
+            d_namespace = "";
+            break;
+    }
+}
+
+/** Get the size of a response, in kilobytes. This method looks at the
+ * variables in the DMR a computes the number of bytes in the response.
+ *
+ * @note This version of the method does a poor job with Arrays that
+ * have varying dimensions.
+ *
+ * @param constrained Should the size of the whole DMR be used or should the
+ * current constraint be taken into account?
+ * @return The size of the request in kilobytes
+ */
+long
+DMR::request_size(bool constrained)
+{
+    return d_root->request_size(constrained);
+}
+
+/**
+ * Print the DAP4 DMR object.
+ *
+ * @param xml use this XMLWriter to build the XML.
+ * @param constrained Should the DMR be subject to a constraint? Defaults to
+ * False
+ */
+void
+DMR::print_dap4(XMLWriter &xml, bool constrained)
+{
+    if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Dataset") < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write Dataset element");
+
+#if 0
+    // Reintroduce these if they are really useful. jhrg 4/15/13
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:xml",
+            (const xmlChar*) c_xml_namespace.c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:xml");
+
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:xsi", (const xmlChar*) c_xml_xsi.c_str())
+            < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:xsi");
+
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xsi:schemaLocation",
+            (const xmlChar*) c_dap_40_n_sl.c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:schemaLocation");
+#endif
+
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns", (const xmlChar*) get_namespace().c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns");
+
+    if (!request_xml_base().empty()) {
+        if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xml:base",
+                (const xmlChar*)request_xml_base().c_str()) < 0)
+            throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xml:base");
+    }
+
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "dapVersion",  (const xmlChar*)dap_version().c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for dapVersion");
+
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "dmrVersion", (const xmlChar*)dmr_version().c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for dapVersion");
+
+    if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
+
+    root()->print_dap4(xml, constrained);
+
+    if (xmlTextWriterEndElement(xml.get_writer()) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not end the top-level Group element");
+}
+
+
+/** @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
+DMR::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "DMR::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    strm << DapIndent::LMarg << "factory: " << (void *)d_factory << endl ;
+    strm << DapIndent::LMarg << "name: " << d_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;
+
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
diff --git a/DMR.h b/DMR.h
new file mode 100644
index 0000000..a5ae1fb
--- /dev/null
+++ b/DMR.h
@@ -0,0 +1,185 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 _dmr_h
+#define _dmr_h 1
+
+#include <cassert>
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+//#include "D4Group.h"
+//#include "XMLWriter.h"
+#include "DapObj.h"
+
+namespace libdap
+{
+
+class D4Group;
+class D4BaseTypeFactory;
+class XMLWriter;
+
+class DDS;
+
+/** DMR is root object for a DAP4 dataset. It holds a D4Group and other
+ * information about the dataset (DAP protocol number, DMR version, etc.).
+ *
+ * @note This class holds the dataset name and filename (which might
+ * actually be a database name, but it's usually a filename). The variables
+ * of a DAP4 dataset are held by the D4Group instance (which is a child
+ * of Constructor).
+ */
+class DMR : public DapObj
+{
+private:
+    D4BaseTypeFactory *d_factory;
+
+    /// The name of the dataset. This should not be the pathname to a file
+    string d_name;
+    /// The pathname or other system identifier for the dataset
+    string d_filename;
+
+    /// DAP protocol major version number. Should be '4'
+    int d_dap_major;
+    /// DAP protocol minor version number.
+    int d_dap_minor;
+    /// String version of the DAP protocol number
+    string d_dap_version;
+
+    /// The version of the DMR document
+    string d_dmr_version;
+
+    /// The URL for the request base
+    string d_request_xml_base;
+
+    /// The namespace to use when printing the XML serialization
+    string d_namespace;
+
+    /// The maximum response size (in Kilo bytes)
+    long d_max_response_size;
+
+    /// The root group; holds dimensions, enums, variables, groups, ...
+    D4Group *d_root;
+
+    friend class DMRTest;
+
+protected:
+    void m_duplicate(const DMR &dmr);
+
+public:
+    DMR();
+    DMR(const DMR &dmr);
+    DMR(D4BaseTypeFactory *factory, const string &name = "");
+
+    DMR(D4BaseTypeFactory *factory, DDS &dds);
+
+    virtual ~DMR();
+
+    DMR &operator=(const DMR &rhs);
+
+    virtual void build_using_dds(DDS &dds);
+
+    /**
+     * Class invariant. If true, any method can be used.
+     * @return True if the instance is OK to use, false otherwise.
+     */
+    bool OK() const { return (d_factory && d_root && !d_dap_version.empty()); }
+
+    /** Get and set the DMR's name. This is effectively the 'dataset' name.
+     * It should not be used to reference the dataset's data store
+     * (e.g., it should not be a pathname to a file). This will be used in
+     * error messages.
+     */
+    //@{
+    string name() const { return d_name; }
+    void set_name(const string &n) { d_name = n; }
+    //@}
+
+    /** Get/set the factory which makes instances of the variables.
+        Specialize D4BaseTypeFactory so that a DMR will be
+        populated with your client or server's specialized types.*/
+    //@{
+    virtual D4BaseTypeFactory *factory() { return d_factory; }
+    virtual void set_factory(D4BaseTypeFactory *f) { d_factory = f; }
+    //@}
+
+    /** get/set the dataset's 'filename.' The filename is a string that can
+     * be used to access the dataset's actual data store (it's usually a
+     * pathname to a file, but it might be a database key.
+     *
+     * @todo Move this to Group?
+     */
+    //@{
+    string filename() const { return d_filename; }
+    void set_filename(const string &fn) { d_filename = fn;}
+    //@}
+
+    string dap_version() const { return d_dap_version; }
+    void set_dap_version(const string &version_string);
+    int dap_major() const { return d_dap_major; }
+    int dap_minor() const { return d_dap_minor; }
+
+    string dmr_version() const { return d_dmr_version; }
+    void set_dmr_version(const string &v) { d_dmr_version = v; }
+
+    /// Get the URL that will return this DMR/DDX/DataThing
+    string 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; }
+
+    /// Get the namespace associated with the DDS - likely set only by DDX responses
+    string get_namespace() const { return d_namespace; }
+
+    /// Set the namespace for this DDS/DDX object/response
+    void set_namespace(const string &ns) { d_namespace = ns; }
+
+    // TODO Move the response_limit methods to D4ResponseBuilder? jhrg 5/1/13
+    /// Get the maximum response size, in KB. Zero indicates no limit.
+    long response_limit() { return d_max_response_size; }
+
+    /** Set the maximum response size. Zero is the default value. The size
+        is given in kilobytes.
+        @param size The maximum size of the response in kilobytes. */
+    void set_response_limit(long size) { d_max_response_size = size; }
+
+    /// Get the estimated response size, in kilo bytes
+    long request_size(bool constrained);
+
+    /** Return the root group of this Dataset. If no root group has been
+     * set, use the D4BaseType factory to make it.
+     * @return The root group of the dataset.
+     */
+    D4Group *root();
+
+    void print_dap4(XMLWriter &xml, bool constrained = false);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _dmr_h
diff --git a/DODSFilter.cc b/DODSFilter.cc
index 6779e65..7b41468 100644
--- a/DODSFilter.cc
+++ b/DODSFilter.cc
@@ -166,7 +166,7 @@ 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_dap2ce: " << d_dap2ce << 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);
@@ -193,7 +193,7 @@ DODSFilter::initialize()
     d_bad_options = false;
     d_conditional_request = false;
     d_dataset = "";
-    d_ce = "";
+    d_dap2ce = "";
     d_cgi_ver = "";
     d_anc_dir = "";
     d_anc_file = "";
@@ -343,13 +343,13 @@ question mark.
 string
 DODSFilter::get_ce() const
 {
-    return d_ce;
+    return d_dap2ce;
 }
 
 void
 DODSFilter::set_ce(string _ce)
 {
-    d_ce = www2id(_ce, "%", "%20");
+    d_dap2ce = www2id(_ce, "%", "%20");
 }
 
 /** The ``dataset name'' is the filename or other string that the
@@ -782,7 +782,7 @@ DODSFilter::send_dds(ostream &out, DDS &dds, ConstraintEvaluator &eval,
 {
     // If constrained, parse the constraint. Throws Error or InternalErr.
     if (constrained)
-        eval.parse_constraint(d_ce, dds);
+        eval.parse_constraint(d_dap2ce, 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.");
@@ -889,7 +889,7 @@ DODSFilter::dataset_constraint_ddx(DDS & dds, ConstraintEvaluator & eval,
                                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);
+    set_mime_ddx_boundary(out, boundary, start, dods_ddx);
 
     // Make cid
     uuid_t uu;
@@ -985,7 +985,7 @@ DODSFilter::send_data(DDS & dds, ConstraintEvaluator & eval,
     establish_timeout(data_stream);
     dds.set_timeout(d_timeout);
 
-    eval.parse_constraint(d_ce, dds);   // Throws Error if the ce doesn't
+    eval.parse_constraint(d_dap2ce, dds);   // Throws Error if the ce doesn't
 					// parse.
 
     dds.tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
@@ -1065,8 +1065,8 @@ 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 (!d_dap2ce.empty())
+        eval.parse_constraint(d_dap2ce, 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.");
@@ -1083,8 +1083,8 @@ DODSFilter::send_ddx(DDS &dds, ConstraintEvaluator &eval, ostream &out,
     }
     else {
         if (with_mime_headers)
-            set_mime_text(out, dap4_ddx, d_cgi_ver, x_plain, dds_lmt);
-        dds.print_xml_writer(out, !d_ce.empty(), "");
+            set_mime_text(out, dods_ddx, d_cgi_ver, x_plain, dds_lmt);
+        dds.print_xml_writer(out, !d_dap2ce.empty(), "");
     }
 }
 
@@ -1128,7 +1128,7 @@ DODSFilter::send_data_ddx(DDS & dds, ConstraintEvaluator & eval,
     establish_timeout(data_stream);
     dds.set_timeout(d_timeout);
 
-    eval.parse_constraint(d_ce, dds);   // Throws Error if the ce doesn't
+    eval.parse_constraint(d_dap2ce, dds);   // Throws Error if the ce doesn't
 					// parse.
 
     dds.tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
@@ -1143,14 +1143,14 @@ DODSFilter::send_data_ddx(DDS & dds, ConstraintEvaluator & eval,
             throw Error(unknown_error, "Error calling the CE function.");
 
         if (with_mime_headers)
-            set_mime_multipart(data_stream, boundary, start, dap4_data_ddx,
+            set_mime_multipart(data_stream, boundary, start, dods_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);
+        serialize_dap2_data_ddx(var_dds, eval, data_stream, boundary, start);
 
         // functional_constraint_ddx(*var, dds, eval, data_stream, boundary);
         delete var;
@@ -1160,7 +1160,7 @@ DODSFilter::send_data_ddx(DDS & dds, ConstraintEvaluator & eval,
     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,
+            set_mime_multipart(data_stream, boundary, start, dods_data_ddx,
         	    d_cgi_ver, x_plain, data_lmt);
         data_stream << flush ;
         dataset_constraint(*fdds, eval, data_stream, false);
@@ -1168,7 +1168,7 @@ DODSFilter::send_data_ddx(DDS & dds, ConstraintEvaluator & eval,
     }
     else {
         if (with_mime_headers)
-            set_mime_multipart(data_stream, boundary, start, dap4_data_ddx,
+            set_mime_multipart(data_stream, boundary, start, dods_data_ddx,
         	    d_cgi_ver, x_plain, data_lmt);
         data_stream << flush ;
         dataset_constraint_ddx(dds, eval, data_stream, boundary, start);
diff --git a/DODSFilter.h b/DODSFilter.h
index 4b6b2bc..a9b9aae 100644
--- a/DODSFilter.h
+++ b/DODSFilter.h
@@ -97,7 +97,7 @@ protected:
 
     string d_program_name; // Name of the filter program
     string d_dataset;  // Name of the dataset/database
-    string d_ce;  // Constraint expression
+    string d_dap2ce;  // DAP2 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
diff --git a/DapIndent.cc b/DapIndent.cc
index 9befc4b..2369124 100644
--- a/DapIndent.cc
+++ b/DapIndent.cc
@@ -33,6 +33,8 @@
 // Methods for the class DapIndent - an indentation class to support
 // debugging and the dump methods.
 
+#include "config.h"
+
 #include "DapIndent.h"
 
 namespace libdap {
diff --git a/DapObj.h b/DapObj.h
index b7192dd..388cb94 100644
--- a/DapObj.h
+++ b/DapObj.h
@@ -64,16 +64,6 @@ public:
      * 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 ;
@@ -87,15 +77,6 @@ public:
  * 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
  */
diff --git a/DapXmlNamespaces.cc b/DapXmlNamespaces.cc
new file mode 100644
index 0000000..e69de29
diff --git a/DapXmlNamespaces.h b/DapXmlNamespaces.h
new file mode 100644
index 0000000..7b29430
--- /dev/null
+++ b/DapXmlNamespaces.h
@@ -0,0 +1,170 @@
+/*
+ * DapXmlNamspaces.h
+ *
+ *  Created on: Feb 19, 2014
+ *      Author: ndp
+ */
+
+#ifndef DAPXMLNAMSPACES_H_
+#define DAPXMLNAMSPACES_H_
+
+
+namespace libdap {
+
+enum DAPVersion { DAP_2_0, DAP_3_2, DAP_4_0 };
+
+class DapXmlNamspaces {
+private:
+
+	 string c_xml_xsi;
+
+	 string c_xml_namespace;
+
+	 string grddl_transformation_dap32;
+
+	 string c_default_dap20_schema_location;
+	 string c_default_dap32_schema_location;
+	 string c_default_dap40_schema_location;
+
+	 string c_dap20_namespace;
+	 string c_dap32_namespace;
+	 string c_dap40_namespace;
+
+public:
+
+	DapXmlNamspaces(){
+		 c_xml_xsi = "http://www.w3.org/2001/XMLSchema-instance";
+		 c_xml_namespace = "http://www.w3.org/XML/1998/namespace";
+
+		 grddl_transformation_dap32 = "http://xml.opendap.org/transforms/ddxToRdfTriples.xsl";
+
+		 c_default_dap20_schema_location = "http://xml.opendap.org/dap/dap2.xsd";
+		 c_default_dap32_schema_location = "http://xml.opendap.org/dap/dap3.2.xsd";
+		 c_default_dap40_schema_location = "http://xml.opendap.org/dap/dap4.0.xsd";
+
+		 c_dap20_namespace = "http://xml.opendap.org/ns/DAP2";
+		 c_dap32_namespace = "http://xml.opendap.org/ns/DAP/3.2#";
+		 c_dap40_namespace = "http://xml.opendap.org/ns/DAP/4.0#";
+
+	};
+	virtual ~DapXmlNamspaces(){};
+
+	/**
+	 * Returns the XML Schema-instance namespace string.
+	 */
+	string getXmlXsiNamespace(){
+		return c_xml_xsi;
+	}
+
+	/**
+	 * Returns the XML  namespace string.
+	 */
+	string getXmlNamespace(){
+		return c_xml_namespace;
+	}
+
+	/**
+	 * Returns the GRDDL transformation URL for the passed DAP version.
+	 */
+	string getGrddlTransformation(DAPVersion version){
+		switch(version) {
+		case DAP_2_0:
+			throw InternalErr(__FILE__, __LINE__, "DapXmlNamspaces::getDapXmlNamespaceString() - GRDDL Transformation undefined for DAP 2.0");
+			break;
+
+		case DAP_3_2:
+			return grddl_transformation_dap32;
+			break;
+
+		case DAP_4_0:
+			throw InternalErr(__FILE__, __LINE__, "DapXmlNamspaces::getDapXmlNamespaceString() - GRDDL Transformation undefined for DAP 4.0");
+			break;
+
+		default:
+			throw InternalErr(__FILE__, __LINE__, "DapXmlNamspaces::getDapXmlNamespaceString() - Unrecognized namespace version.");
+			break;
+		}
+		return 0;
+	}
+
+
+
+	/**
+	 * Returns the DAP XML namespace string for the passed DAP version.
+	 */
+	string getDapNamespaceString(DAPVersion version){
+		switch(version) {
+		case DAP_2_0:
+			return c_dap20_namespace;
+			break;
+
+		case DAP_3_2:
+			return c_dap32_namespace;
+			break;
+
+		case DAP_4_0:
+			return c_dap40_namespace;
+			break;
+
+		default:
+			throw InternalErr(__FILE__, __LINE__, "DapXmlNamspaces::getDapXmlNamespaceString() - Unrecognized namespace version.");
+			break;
+		}
+		return 0;
+	}
+
+	/**
+	 * Returns the schema location URI string for the passed DAP version.
+	 */
+	string getSchemaLocationString(DAPVersion version){
+		switch(version) {
+		case DAP_2_0:
+			return c_default_dap20_schema_location;
+			break;
+
+		case DAP_3_2:
+			return c_default_dap32_schema_location;
+			break;
+
+		case DAP_4_0:
+			return c_default_dap40_schema_location;
+			break;
+
+		default:
+			throw InternalErr(__FILE__, __LINE__, "DapXmlNamspaces::getSchemaLocationString() - Unrecognized namespace version.");
+			break;
+		}
+		return 0;
+	}
+
+
+
+	/**
+	 * Returns the schema location declaration (the namespace string followed by a
+	 * space followed by the schema location string) for the passed DAP version.
+	 */
+	string getSchemaLocationDeclarationString(DAPVersion version){
+		switch(version) {
+		case DAP_2_0:
+			return c_dap20_namespace + " " + c_default_dap20_schema_location;
+			break;
+
+		case DAP_3_2:
+			return c_dap32_namespace + " " + c_default_dap32_schema_location;
+			break;
+
+		case DAP_4_0:
+			return c_dap40_namespace + " " + c_default_dap40_schema_location;
+			break;
+
+		default:
+			throw InternalErr(__FILE__, __LINE__, "DapXmlNamspaces::getSchemaLocationDeclarationString() - Unrecognized namespace version.");
+			break;
+		}
+		return 0;
+	}
+
+};
+
+} /* namespace libdap */
+#endif /* DAPXMLNAMSPACES_H_ */
diff --git a/Error.cc b/Error.cc
index c3397b6..27e2f78 100644
--- a/Error.cc
+++ b/Error.cc
@@ -34,10 +34,6 @@
 
 #include "config.h"
 
-static char rcsid[] not_used =
-    {"$Id: Error.cc 27197 2013-10-01 21:29:54Z jimg $"
-    };
-
 #include <cstdio>
 #include <cassert>
 
diff --git a/Error.lex b/Error.lex
index 1a8f5ea..eca439e 100644
--- a/Error.lex
+++ b/Error.lex
@@ -41,7 +41,7 @@
 
 #include "config_dap.h"
 
-static char rcsid[] not_used = {"$Id: Error.lex 27157 2013-09-28 21:22:52Z jimg $"};
+static char rcsid[] not_used = {"$Id$"};
 
 #include <cstdlib>
 #include <cassert>
diff --git a/Error.tab.cc b/Error.tab.cc
index 720728b..abc8dd5 100644
--- a/Error.tab.cc
+++ b/Error.tab.cc
@@ -1,21 +1,19 @@
+/* A Bison parser, made by GNU Bison 3.0.1.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* Bison implementation for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
 
-/* 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 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 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/>.  */
 
@@ -28,7 +26,7 @@
    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.  */
 
@@ -46,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "3.0.1"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -60,29 +58,28 @@
 /* Pull parsers.  */
 #define YYPULL 1
 
-/* 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
 
+#define yylval          Errorlval
+#define yychar          Errorchar
 
 /* Copy the first part of user declarations.  */
 
+#line 75 "Error.tab.cc" /* yacc.c:339  */
 
-/* Line 189 of yacc.c  */
-#line 81 "Error.tab.cc"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -92,15 +89,19 @@
 # define YYERROR_VERBOSE 0
 #endif
 
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+   by #include "Error.tab.hh".  */
+#ifndef YY_ERROR_ERROR_TAB_HH_INCLUDED
+# define YY_ERROR_ERROR_TAB_HH_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int Errordebug;
 #endif
-
 /* "%code requires" blocks.  */
-
-/* Line 209 of yacc.c  */
-#line 32 "Error.yy"
+#line 32 "Error.yy" /* yacc.c:355  */
 
 
 #include "config_dap.h"
@@ -129,33 +130,27 @@ using namespace libdap;
 extern int error_line_num;	// defined in Error.lex
 
 
+#line 134 "Error.tab.cc" /* yacc.c:355  */
 
-
-/* Line 209 of yacc.c  */
-#line 136 "Error.tab.cc"
-
-/* Tokens.  */
+/* Token type.  */
 #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
-   };
+  enum yytokentype
+  {
+    SCAN_INT = 258,
+    SCAN_STR = 259,
+    SCAN_ERROR = 260,
+    SCAN_CODE = 261,
+    SCAN_MSG = 262
+  };
 #endif
 
-
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
 {
-
-/* Line 214 of yacc.c  */
-#line 75 "Error.yy"
+#line 75 "Error.yy" /* yacc.c:355  */
 
 #ifdef __SUNPRO_CC
     int boolean;
@@ -165,36 +160,31 @@ typedef union YYSTYPE
     int integer;
     char *string;
 
-
-
-/* Line 214 of yacc.c  */
-#line 172 "Error.tab.cc"
-} YYSTYPE;
+#line 164 "Error.tab.cc" /* yacc.c:355  */
+};
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
 
-/* Copy the second part of user declarations.  */
+extern YYSTYPE Errorlval;
 
+int Errorparse (parser_arg *arg);
 
-/* Line 264 of yacc.c  */
-#line 184 "Error.tab.cc"
-/* Unqualified %code blocks.  */
+#endif /* !YY_ERROR_ERROR_TAB_HH_INCLUDED  */
 
-/* Line 265 of yacc.c  */
-#line 61 "Error.yy"
+/* Copy the second part of user declarations.  */
+
+#line 179 "Error.tab.cc" /* yacc.c:358  */
+/* Unqualified %code blocks.  */
+#line 61 "Error.yy" /* yacc.c:359  */
 
 
 int Errorlex();			// the scanner
 void Errorerror(parser_arg *arg, const string &s);	// gotta love automatically generated names...
 
 
-
-
-/* Line 265 of yacc.c  */
-#line 198 "Error.tab.cc"
+#line 188 "Error.tab.cc" /* yacc.c:359  */
 
 #ifdef short
 # undef short
@@ -208,11 +198,8 @@ typedef unsigned char yytype_uint8;
 
 #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;
+typedef signed char yytype_int8;
 #endif
 
 #ifdef YYTYPE_UINT16
@@ -232,8 +219,7 @@ typedef short int yytype_int16;
 #  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)
+# elif ! defined YYSIZE_T
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
@@ -244,41 +230,70 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(msgid) msgid
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
 #else
-# define YYUSE(e) /* empty */
+# 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 yyi)
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
 #else
-static int
-YYID (yyi)
-    int yyi;
+# define YY_INITIAL_VALUE(Value) Value
 #endif
-{
-  return yyi;
-}
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
 #endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
 
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
@@ -297,11 +312,11 @@ YYID (yyi)
 #    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)
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -309,8 +324,8 @@ YYID (yyi)
 # endif
 
 # ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+   /* Pacify GCC's 'empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (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
@@ -324,25 +339,23 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
-	     && (defined YYFREE || defined free)))
+             && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
+#   if ! defined malloc && ! defined EXIT_SUCCESS
 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)
+#   if ! defined free && ! defined EXIT_SUCCESS
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
@@ -352,7 +365,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
-	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
@@ -370,42 +383,46 @@ union yyalloc
      ((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
+# define YYCOPY_NEEDED 1
 
 /* 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_alloc, Stack)				\
-    do									\
-      {									\
-	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
-	Stack = &yyptr->Stack_alloc;					\
-	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-	yyptr += yynewbytes / sizeof (*yyptr);				\
-      }									\
-    while (YYID (0))
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
+    do                                                                  \
+      {                                                                 \
+        YYSIZE_T yynewbytes;                                            \
+        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+        Stack = &yyptr->Stack_alloc;                                    \
+        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                 \
+    while (0)
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (0)
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  4
 /* YYLAST -- Last index in YYTABLE.  */
@@ -417,17 +434,19 @@ union yyalloc
 #define YYNNTS  7
 /* YYNRULES -- Number of rules.  */
 #define YYNRULES  8
-/* YYNRULES -- Number of states.  */
+/* YYNSTATES -- Number of states.  */
 #define YYNSTATES  20
 
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   262
 
-#define YYTRANSLATE(YYX)						\
+#define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, without out-of-bounds checking.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -460,42 +479,27 @@ static const yytype_uint8 yytranslate[] =
 };
 
 #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.  */
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
        0,   103,   103,   106,   109,   110,   113,   121,   120
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
 /* 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
+  "error_object", "contents", "description", "code", "message", "$@1", YY_NULLPTR
 };
 #endif
 
 # ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+   (internal) symbol number NUM (which must be that of a token).  */
 static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   123,   125,
@@ -503,53 +507,48 @@ static const yytype_uint16 yytoknum[] =
 };
 # 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
-};
+#define YYPACT_NINF -8
 
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-8)))
+
+#define YYTABLE_NINF -1
+
+#define yytable_value_is_error(Yytable_value) \
+  0
+
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
+static const yytype_int8 yypact[] =
 {
-       0,     2,     5,     1,     2,     1,     4,     0,     5
+      -5,    -7,     2,    -3,    -8,    -6,    -2,    -8,    -1,     1,
+       0,     3,    -8,     5,    -8,     4,    -8,    -8,     6,    -8
 };
 
-/* 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.  */
+  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+     Performed when YYTABLE does not 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[] =
+  /* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
 {
-      -5,    -7,     2,    -3,    -8,    -6,    -2,    -8,    -1,     1,
-       0,     3,    -8,     5,    -8,     4,    -8,    -8,     6,    -8
+      -8,    -8,    -8,    -8,    -8,    -8,    -8
 };
 
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int8 yypgoto[] =
+  /* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
 {
-      -8,    -8,    -8,    -8,    -8,    -8,    -8
+      -1,     2,     6,     7,     8,    12,    18
 };
 
-/* 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
+  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule whose
+     number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_uint8 yytable[] =
 {
        1,     3,     4,     5,    13,     9,    11,    10,    17,     0,
@@ -562,104 +561,62 @@ static const yytype_int8 yycheck[] =
       10,    -1,    -1,    -1,    11,    10,    10
 };
 
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
+  /* 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
+  /* 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 on the right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     5,     1,     2,     1,     4,     0,     5
+};
 
-#define YYACCEPT	goto yyacceptlab
-#define YYABORT		goto yyabortlab
-#define YYERROR		goto yyerrorlab
 
+#define yyerrok         (yyerrstatus = 0)
+#define yyclearin       (yychar = YYEMPTY)
+#define YYEMPTY         (-2)
+#define YYEOF           0
 
-/* 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 YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
 
-#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								\
-    {								\
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
       yyerror (arg, 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
-
+      YYERROR;                                                  \
+    }                                                           \
+while (0)
 
-/* 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.  */
+/* Error token number */
+#define YYTERROR        1
+#define YYERRCODE       256
 
-#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
 
@@ -668,56 +625,47 @@ while (YYID (0))
 #  define YYFPRINTF fprintf
 # endif
 
-# define YYDPRINTF(Args)			\
-do {						\
-  if (yydebug)					\
-    YYFPRINTF Args;				\
-} while (YYID (0))
+# define YYDPRINTF(Args)                        \
+do {                                            \
+  if (yydebug)                                  \
+    YYFPRINTF Args;                             \
+} while (0)
 
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
-do {									  \
-  if (yydebug)								  \
-    {									  \
-      YYFPRINTF (stderr, "%s ", Title);					  \
-      yy_symbol_print (stderr,						  \
-		  Type, Value, arg); \
-      YYFPRINTF (stderr, "\n");						  \
-    }									  \
-} while (YYID (0))
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
+do {                                                                      \
+  if (yydebug)                                                            \
+    {                                                                     \
+      YYFPRINTF (stderr, "%s ", Title);                                   \
+      yy_symbol_print (stderr,                                            \
+                  Type, Value, arg); \
+      YYFPRINTF (stderr, "\n");                                           \
+    }                                                                     \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value 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, parser_arg *arg)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    parser_arg *arg;
-#endif
 {
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
+  YYUSE (arg);
   if (!yyvaluep)
     return;
-  YYUSE (arg);
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
-  YYUSE (yyoutput);
 # endif
-  switch (yytype)
-    {
-      default:
-	break;
-    }
+  YYUSE (yytype);
 }
 
 
@@ -725,23 +673,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg)
 | 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, parser_arg *arg)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, arg)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    parser_arg *arg;
-#endif
 {
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-  else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+  YYFPRINTF (yyoutput, "%s %s (",
+             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
   yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg);
   YYFPRINTF (yyoutput, ")");
@@ -752,16 +688,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, arg)
 | TOP (included).                                                   |
 `------------------------------------------------------------------*/
 
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
-#endif
 {
   YYFPRINTF (stderr, "Stack now");
   for (; yybottom <= yytop; yybottom++)
@@ -772,50 +700,42 @@ yy_stack_print (yybottom, yytop)
   YYFPRINTF (stderr, "\n");
 }
 
-# define YY_STACK_PRINT(Bottom, Top)				\
-do {								\
-  if (yydebug)							\
-    yy_stack_print ((Bottom), (Top));				\
-} while (YYID (0))
+# define YY_STACK_PRINT(Bottom, Top)                            \
+do {                                                            \
+  if (yydebug)                                                  \
+    yy_stack_print ((Bottom), (Top));                           \
+} while (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, parser_arg *arg)
-#else
-static void
-yy_reduce_print (yyvsp, yyrule, arg)
-    YYSTYPE *yyvsp;
-    int yyrule;
-    parser_arg *arg;
-#endif
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, parser_arg *arg)
 {
+  unsigned long int yylno = yyrline[yyrule];
   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);
+             yyrule - 1, yylno);
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
-		       &(yyvsp[(yyi + 1) - (yynrhs)])
-		       		       , arg);
+      yy_symbol_print (stderr,
+                       yystos[yyssp[yyi + 1 - yynrhs]],
+                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                                              , arg);
       YYFPRINTF (stderr, "\n");
     }
 }
 
-# define YY_REDUCE_PRINT(Rule)		\
-do {					\
-  if (yydebug)				\
-    yy_reduce_print (yyvsp, Rule, arg); \
-} while (YYID (0))
+# define YY_REDUCE_PRINT(Rule)          \
+do {                                    \
+  if (yydebug)                          \
+    yy_reduce_print (yyssp, yyvsp, Rule, arg); \
+} while (0)
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
    multiple parsers can coexist.  */
@@ -829,7 +749,7 @@ int yydebug;
 
 
 /* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef	YYINITDEPTH
+#ifndef YYINITDEPTH
 # define YYINITDEPTH 200
 #endif
 
@@ -844,7 +764,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-

 
 #if YYERROR_VERBOSE
 
@@ -853,15 +772,8 @@ int yydebug;
 #   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++)
@@ -877,16 +789,8 @@ yystrlen (yystr)
 #  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;
@@ -916,27 +820,27 @@ yytnamerr (char *yyres, const char *yystr)
       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;
-	  }
+        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: ;
     }
 
@@ -947,163 +851,161 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # 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)
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
+
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
 {
-  int yyn = yypact[yystate];
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULLPTR;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
+    {
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          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 yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (! (yysize <= yysize1
+                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
+              }
+        }
+    }
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+  switch (yycount)
     {
-      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;
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
+
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
+
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
     }
+
+  /* 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 = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #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, parser_arg *arg)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep, arg)
-    const char *yymsg;
-    int yytype;
-    YYSTYPE *yyvaluep;
-    parser_arg *arg;
-#endif
 {
   YYUSE (yyvaluep);
   YYUSE (arg);
-
   if (!yymsg)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  switch (yytype)
-    {
-
-      default:
-	break;
-    }
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 }
 
-/* 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 (parser_arg *arg);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
+
 
 
 /* The lookahead symbol.  */
@@ -1111,49 +1013,26 @@ int yychar;
 
 /* The semantic value of the lookahead symbol.  */
 YYSTYPE yylval;
-
 /* Number of syntax errors so far.  */
 int yynerrs;
 
 
+/*----------.
+| yyparse.  |
+`----------*/
 
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
-
-#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 (parser_arg *arg)
-#else
-int
-yyparse (arg)
-    parser_arg *arg;
-#endif
-#endif
 {
-
-
     int yystate;
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
 
     /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
+       'yyss': related to states.
+       'yyvs': related to semantic values.
 
-       Refer to the stacks thru separate pointers, to allow yyoverflow
+       Refer to the stacks through separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
 
     /* The state stack.  */
@@ -1171,7 +1050,7 @@ yyparse (arg)
   int yyn;
   int yyresult;
   /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
+  int yytoken = 0;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
@@ -1189,9 +1068,8 @@ yyparse (arg)
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
   yystacksize = YYINITDEPTH;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1200,14 +1078,6 @@ yyparse (arg)
   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;
 
 /*------------------------------------------------------------.
@@ -1228,23 +1098,23 @@ yyparse (arg)
 
 #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;
+        /* 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
@@ -1252,22 +1122,22 @@ yyparse (arg)
 # else
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
-	goto yyexhaustedlab;
+        goto yyexhaustedlab;
       yystacksize *= 2;
       if (YYMAXDEPTH < yystacksize)
-	yystacksize = YYMAXDEPTH;
+        yystacksize = YYMAXDEPTH;
 
       {
-	yytype_int16 *yyss1 = yyss;
-	union yyalloc *yyptr =
-	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-	if (! yyptr)
-	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss_alloc, yyss);
-	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+        yytype_int16 *yyss1 = yyss;
+        union yyalloc *yyptr =
+          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+        if (! yyptr)
+          goto yyexhaustedlab;
+        YYSTACK_RELOCATE (yyss_alloc, yyss);
+        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
 #  undef YYSTACK_RELOCATE
-	if (yyss1 != yyssa)
-	  YYSTACK_FREE (yyss1);
+        if (yyss1 != yyssa)
+          YYSTACK_FREE (yyss1);
       }
 # endif
 #endif /* no yyoverflow */
@@ -1276,10 +1146,10 @@ yyparse (arg)
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-		  (unsigned long int) yystacksize));
+                  (unsigned long int) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
-	YYABORT;
+        YYABORT;
     }
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1299,7 +1169,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -1308,7 +1178,7 @@ yybackup:
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = YYLEX;
+      yychar = yylex ();
     }
 
   if (yychar <= YYEOF)
@@ -1330,8 +1200,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -1348,7 +1218,9 @@ yybackup:
   yychar = YYEMPTY;
 
   yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -1371,7 +1243,7 @@ yyreduce:
   yylen = yyr2[yyn];
 
   /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
+     '$$ = $1'.
 
      Otherwise, the following line sets YYVAL to garbage.
      This behavior is undocumented and Bison
@@ -1385,67 +1257,69 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-
-/* Line 1455 of yacc.c  */
-#line 103 "Error.yy"
-    { (yyval.boolean) = (yyvsp[(3) - (5)].boolean); STATUS(arg) = (yyvsp[(3) - (5)].boolean); ;}
+#line 103 "Error.yy" /* yacc.c:1646  */
+    { (yyval.boolean) = (yyvsp[-2].boolean); STATUS(arg) = (yyvsp[-2].boolean); }
+#line 1263 "Error.tab.cc" /* yacc.c:1646  */
     break;
 
   case 3:
-
-/* Line 1455 of yacc.c  */
-#line 106 "Error.yy"
-    { (yyval.boolean) = (yyvsp[(1) - (1)].boolean); ;}
+#line 106 "Error.yy" /* yacc.c:1646  */
+    { (yyval.boolean) = (yyvsp[0].boolean); }
+#line 1269 "Error.tab.cc" /* yacc.c:1646  */
     break;
 
   case 4:
-
-/* Line 1455 of yacc.c  */
-#line 109 "Error.yy"
-    { (yyval.boolean) = (yyvsp[(1) - (2)].boolean) && (yyvsp[(2) - (2)].boolean); ;}
+#line 109 "Error.yy" /* yacc.c:1646  */
+    { (yyval.boolean) = (yyvsp[-1].boolean) && (yyvsp[0].boolean); }
+#line 1275 "Error.tab.cc" /* yacc.c:1646  */
     break;
 
   case 5:
-
-/* Line 1455 of yacc.c  */
-#line 110 "Error.yy"
-    { (yyval.boolean) = (yyvsp[(1) - (1)].boolean); ;}
+#line 110 "Error.yy" /* yacc.c:1646  */
+    { (yyval.boolean) = (yyvsp[0].boolean); }
+#line 1281 "Error.tab.cc" /* yacc.c:1646  */
     break;
 
   case 6:
-
-/* Line 1455 of yacc.c  */
-#line 114 "Error.yy"
+#line 114 "Error.yy" /* yacc.c:1646  */
     { 
-		    ERROR_OBJ(arg)->set_error_code((ErrorCode)(yyvsp[(3) - (4)].integer));
+		    ERROR_OBJ(arg)->set_error_code((ErrorCode)(yyvsp[-1].integer));
 		    (yyval.boolean) = true; 
-		;}
+		}
+#line 1290 "Error.tab.cc" /* yacc.c:1646  */
     break;
 
   case 7:
-
-/* Line 1455 of yacc.c  */
-#line 121 "Error.yy"
+#line 121 "Error.yy" /* yacc.c:1646  */
     { 
-		    ERROR_OBJ(arg)->set_error_message((yyvsp[(3) - (3)].string));
-		;}
+		    ERROR_OBJ(arg)->set_error_message((yyvsp[0].string));
+		}
+#line 1298 "Error.tab.cc" /* yacc.c:1646  */
     break;
 
   case 8:
-
-/* Line 1455 of yacc.c  */
-#line 125 "Error.yy"
+#line 125 "Error.yy" /* yacc.c:1646  */
     {
 		    (yyval.boolean) = true;
-		;}
+		}
+#line 1306 "Error.tab.cc" /* yacc.c:1646  */
     break;
 
 
-
-/* Line 1455 of yacc.c  */
-#line 1447 "Error.tab.cc"
+#line 1310 "Error.tab.cc" /* yacc.c:1646  */
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -1454,7 +1328,7 @@ yyreduce:
 
   *++yyvsp = yyval;
 
-  /* Now `shift' the result of the reduction.  Determine what state
+  /* 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.  */
 
@@ -1469,10 +1343,14 @@ yyreduce:
   goto yynewstate;
 
 
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
+/*--------------------------------------.
+| yyerrlab -- here on detecting error.  |
+`--------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -1480,37 +1358,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (arg, YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-	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 (arg, yymsg);
-	  }
-	else
-	  {
-	    yyerror (arg, YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (arg, yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -1519,20 +1396,20 @@ yyerrlab:
   if (yyerrstatus == 3)
     {
       /* If just tried and failed to reuse lookahead token after an
-	 error, discard it.  */
+         error, discard it.  */
 
       if (yychar <= YYEOF)
-	{
-	  /* Return failure if at end of input.  */
-	  if (yychar == YYEOF)
-	    YYABORT;
-	}
+        {
+          /* Return failure if at end of input.  */
+          if (yychar == YYEOF)
+            YYABORT;
+        }
       else
-	{
-	  yydestruct ("Error: discarding",
-		      yytoken, &yylval, arg);
-	  yychar = YYEMPTY;
-	}
+        {
+          yydestruct ("Error: discarding",
+                      yytoken, &yylval, arg);
+          yychar = YYEMPTY;
+        }
     }
 
   /* Else will try to reuse lookahead token after shifting the error
@@ -1551,7 +1428,7 @@ yyerrorlab:
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-  /* Do not reclaim the symbols of the rule which action triggered
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
   yylen = 0;
@@ -1564,35 +1441,37 @@ yyerrorlab:
 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
 `-------------------------------------------------------------*/
 yyerrlab1:
-  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+  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;
-	    }
-	}
+      if (!yypact_value_is_default (yyn))
+        {
+          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;
+        YYABORT;
 
 
       yydestruct ("Error: popping",
-		  yystos[yystate], yyvsp, arg);
+                  yystos[yystate], yyvsp, arg);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
     }
 
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -1616,7 +1495,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -1628,16 +1507,21 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval, arg);
-  /* Do not reclaim the symbols of the rule which action triggered
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval, arg);
+    }
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
   YY_STACK_PRINT (yyss, yyssp);
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-		  yystos[*yyssp], yyvsp, arg);
+                  yystos[*yyssp], yyvsp, arg);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
@@ -1648,14 +1532,9 @@ yyreturn:
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
 #endif
-  /* Make sure YYID is used.  */
-  return YYID (yyresult);
+  return yyresult;
 }
-
-
-
-/* Line 1675 of yacc.c  */
-#line 130 "Error.yy"
+#line 130 "Error.yy" /* yacc.c:1906  */
 
 
 void
@@ -1669,4 +1548,3 @@ Errorerror(parser_arg *, const string &s)
   throw Error(unknown_error, msg);
 }
 
-
diff --git a/Error.tab.hh b/Error.tab.hh
index b8ba15f..e369b06 100644
--- a/Error.tab.hh
+++ b/Error.tab.hh
@@ -1,21 +1,19 @@
+/* A Bison parser, made by GNU Bison 3.0.1.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* Bison interface for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
 
-/* 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 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 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/>.  */
 
@@ -28,14 +26,21 @@
    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.  */
 
+#ifndef YY_ERROR_ERROR_TAB_HH_INCLUDED
+# define YY_ERROR_ERROR_TAB_HH_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int Errordebug;
+#endif
 /* "%code requires" blocks.  */
-
-/* Line 1676 of yacc.c  */
-#line 32 "Error.yy"
+#line 32 "Error.yy" /* yacc.c:1909  */
 
 
 #include "config_dap.h"
@@ -64,33 +69,27 @@ using namespace libdap;
 extern int error_line_num;	// defined in Error.lex
 
 
+#line 73 "Error.tab.hh" /* yacc.c:1909  */
 
-
-/* Line 1676 of yacc.c  */
-#line 71 "Error.tab.hh"
-
-/* Tokens.  */
+/* Token type.  */
 #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
-   };
+  enum yytokentype
+  {
+    SCAN_INT = 258,
+    SCAN_STR = 259,
+    SCAN_ERROR = 260,
+    SCAN_CODE = 261,
+    SCAN_MSG = 262
+  };
 #endif
 
-
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
 {
-
-/* Line 1676 of yacc.c  */
-#line 75 "Error.yy"
+#line 75 "Error.yy" /* yacc.c:1909  */
 
 #ifdef __SUNPRO_CC
     int boolean;
@@ -100,16 +99,15 @@ typedef union YYSTYPE
     int integer;
     char *string;
 
-
-
-/* Line 1676 of yacc.c  */
-#line 107 "Error.tab.hh"
-} YYSTYPE;
+#line 103 "Error.tab.hh" /* yacc.c:1909  */
+};
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
+
 extern YYSTYPE Errorlval;
 
+int Errorparse (parser_arg *arg);
 
+#endif /* !YY_ERROR_ERROR_TAB_HH_INCLUDED  */
diff --git a/EventHandler.h b/EventHandler.h
index b27c34b..c2418ed 100644
--- a/EventHandler.h
+++ b/EventHandler.h
@@ -53,6 +53,9 @@ public:
     {}
 };
 
+#if 0
+// moved to SignalHandlerTest jhrg 4/26/13
+
 /** Test Handler. This is used with the SignalHandlerTest unit tests. */
 class TestHandler : public EventHandler
 {
@@ -62,12 +65,11 @@ public:
     TestHandler() : flag(0)
     {}
 
-    virtual void handle_signal(int signum)
-    {
-        std::cerr << "Got signal: " << signum << std::endl;
+    virtual void handle_signal(int ) {
         flag = 1;
     }
 };
+#endif
 
 } // namespace libdap
 
diff --git a/Float32.cc b/Float32.cc
index 09b485a..c1fb7cd 100644
--- a/Float32.cc
+++ b/Float32.cc
@@ -51,10 +51,14 @@
 #include "Str.h"
 #include "Url.h"
 
+#include "DDS.h"
 #include "Marshaller.h"
 #include "UnMarshaller.h"
 
-#include "DDS.h"
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
 #include "util.h"
 #include "parser.h"
 #include "Operators.h"
@@ -74,8 +78,7 @@ namespace libdap {
     @param n A string containing the name of the variable to be
     created.
 */
-Float32::Float32(const string &n)
-        : BaseType(n, dods_float32_c)
+Float32::Float32(const string &n) : BaseType(n, dods_float32_c), d_buf(0)
 {}
 
 /** The Float32 server-side constructor accepts the name of the variable and
@@ -85,8 +88,7 @@ Float32::Float32(const string &n)
     @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 string &n, const string &d) : BaseType(n, d, dods_float32_c), d_buf(0)
 {}
 
 Float32::Float32(const Float32 &copy_from) : BaseType(copy_from)
@@ -114,24 +116,21 @@ Float32::operator=(const Float32 &rhs)
 }
 
 unsigned int
-Float32::width(bool)
+Float32::width(bool) const
 {
     return sizeof(dods_float32);
 }
 
 bool
-Float32::serialize(ConstraintEvaluator &eval, DDS &dds,
-                   Marshaller &m, bool ce_eval)
+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();
 
@@ -148,6 +147,35 @@ Float32::deserialize(UnMarshaller &um, DDS *, bool)
     return false;
 }
 
+void
+Float32::compute_checksum(Crc32 &checksum)
+{
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
+
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+Float32::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+    m.put_float32( d_buf ) ;
+}
+
+void
+Float32::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+    um.get_float32( d_buf ) ;
+}
+
 unsigned int
 Float32::val2buf(void *val, bool)
 {
diff --git a/Float32.h b/Float32.h
index fd900d5..d90cef2 100644
--- a/Float32.h
+++ b/Float32.h
@@ -52,6 +52,8 @@
 namespace libdap
 {
 
+class DMR;
+
 /** @brief Holds a 32-bit floating point value.
 
     @see BaseType
@@ -73,13 +75,17 @@ public:
     {}
 
     virtual BaseType *ptr_duplicate();
+    virtual unsigned int width(bool constrained = false) const;
 
-    virtual unsigned int width(bool constrained = false);
-
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true);
+    // DAP2
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,  Marshaller &m, bool ce_eval = true);
     virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
 
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
     virtual unsigned int val2buf(void *val, bool reuse = false);
     virtual unsigned int buf2val(void **val);
 
diff --git a/Float64.cc b/Float64.cc
index 04cdb70..f05bca8 100644
--- a/Float64.cc
+++ b/Float64.cc
@@ -55,6 +55,10 @@
 #include "Marshaller.h"
 #include "UnMarshaller.h"
 
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
 #include "util.h"
 #include "parser.h"
 #include "Operators.h"
@@ -75,8 +79,7 @@ namespace libdap {
     created.
 
 */
-Float64::Float64(const string &n)
-        : BaseType(n, dods_float64_c)
+Float64::Float64(const string &n) : BaseType(n, dods_float64_c), d_buf(0)
 {}
 
 /** The Float64 server-side constructor accepts the name of the variable and
@@ -86,8 +89,7 @@ Float64::Float64(const string &n)
     @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 string &n, const string &d) : BaseType(n, d, dods_float64_c), d_buf(0)
 {}
 
 Float64::Float64(const Float64 &copy_from) : BaseType(copy_from)
@@ -115,24 +117,21 @@ Float64::operator=(const Float64 &rhs)
 }
 
 unsigned int
-Float64::width(bool)
+Float64::width(bool) const
 {
     return sizeof(dods_float64);
 }
 
 bool
-Float64::serialize(ConstraintEvaluator &eval, DDS &dds,
-                   Marshaller &m, bool ce_eval)
+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();
 
@@ -149,6 +148,35 @@ Float64::deserialize(UnMarshaller &um, DDS *, bool)
     return false;
 }
 
+void
+Float64::compute_checksum(Crc32 &checksum)
+{
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
+
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+Float64::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+    m.put_float64( d_buf ) ;
+}
+
+void
+Float64::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+    um.get_float64( d_buf ) ;
+}
+
 unsigned int
 Float64::val2buf(void *val, bool)
 {
diff --git a/Float64.h b/Float64.h
index 34f41f9..a818100 100644
--- a/Float64.h
+++ b/Float64.h
@@ -73,13 +73,17 @@ public:
     Float64 &operator=(const Float64 &rhs);
 
     virtual BaseType *ptr_duplicate();
+    virtual unsigned int width(bool constrained = false) const;
 
-    virtual unsigned int width(bool constrained = false);
-
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true);
+    // DAP2
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval = true);
     virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
 
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
     virtual unsigned int val2buf(void *val, bool reuse = false);
     virtual unsigned int buf2val(void **val);
 
diff --git a/GNU/GetOpt.cc b/GNU/GetOpt.cc
index fa79ecc..4a8b5a7 100644
--- a/GNU/GetOpt.cc
+++ b/GNU/GetOpt.cc
@@ -36,10 +36,13 @@ char *alloca ();
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#include <string.h>		// Added these. 10/20/98 jhrg
+#include <cstdio>
+#include <cstring>		// Added these. 10/20/98 jhrg
+#include <cstdlib>
+
 #include "GetOpt.h"
-#include <stdlib.h>
-#include <string.h>
+
+//#include <string.h>
 
 char* GetOpt::nextchar = 0;
 int GetOpt::first_nonopt = 0;
diff --git a/GNU/GetOpt.h b/GNU/GetOpt.h
index 1063ccb..c8e618c 100644
--- a/GNU/GetOpt.h
+++ b/GNU/GetOpt.h
@@ -1,4 +1,4 @@
-/* Getopt for GNU. 
+/* Getopt for GNU.
    Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
    (Modified by Douglas C. Schmidt for use with GNU G++.)
 
@@ -15,7 +15,7 @@ License along with this library; if not, write to the Free Software
 Foundation 51 Franklin Street, Suite 500, Boston, MA 02110-1335 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.
@@ -33,7 +33,7 @@ Foundation 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA.
 #ifndef GetOpt_h
 #define GetOpt_h 1
 
-#include <stdio.h>
+// #include <stdio.h>
 
 class GetOpt
 {
@@ -41,51 +41,51 @@ 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.
@@ -93,31 +93,31 @@ public:
      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);
 };
diff --git a/GNU/README b/GNU/README
index 3b300bb..235c008 100644
--- a/GNU/README
+++ b/GNU/README
@@ -1,5 +1,5 @@
 
-	$Id: README 24057 2011-02-02 23:54:21Z jimg $
+	$Id$
 
 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.
diff --git a/Grid.cc b/Grid.cc
index c4b380c..338f0c0 100644
--- a/Grid.cc
+++ b/Grid.cc
@@ -50,6 +50,12 @@
 #include "XDRStreamMarshaller.h"
 #include "debug.h"
 
+#include "XMLWriter.h"
+#include "DMR.h"
+#include "D4Group.h"
+#include "D4Maps.h"
+#include "D4Attributes.h"
+
 using namespace std;
 
 namespace libdap {
@@ -57,22 +63,13 @@ namespace libdap {
 void
 Grid::m_duplicate(const Grid &s)
 {
-    // Clear out any spurious vars in Constructor::d_vars
-    d_vars.clear(); // [mjohnson 10 Sep 2009]
-
-    d_array_var = s.d_array_var->ptr_duplicate();
-    d_array_var->set_parent(this);
-    d_vars.push_back(d_array_var); // so the Constructor::Vars_Iter sees it [mjohnson 10 Sep 2009]
-
-    Grid &cs = const_cast<Grid &>(s);
-
-    for (Map_iter i = cs.d_map_vars.begin(); i != cs.d_map_vars.end(); i++) {
-        BaseType *btp = (*i)->ptr_duplicate();
-        btp->set_parent(this);
-        d_map_vars.push_back(btp);
-        d_vars.push_back(btp); // push all map vectors as weak refs into super::d_vars which won't delete them [mjohnson 10 Sep 2009]
-    }
+    // TODO revisit this code once/if the class is switched from using it's
+    // own vars to those in Constructor. jhrg 4/3/13
 
+	// copy the weak pointer - Constructor will take care of copying
+	// the 'strong' pointers.
+	//d_array_var = s.d_array_var;
+	d_is_array_set = s.d_is_array_set;
 }
 
 /** The Grid constructor requires only the name of the variable
@@ -84,7 +81,7 @@ Grid::m_duplicate(const Grid &s)
 
     @brief The Grid constructor.
 */
-Grid::Grid(const string &n) : Constructor(n, dods_grid_c), d_array_var(0)
+Grid::Grid(const string &n) : Constructor(n, dods_grid_c), d_is_array_set(false)
 {}
 
 /** The Grid server-side constructor requires the name of the variable
@@ -99,7 +96,7 @@ Grid::Grid(const string &n) : Constructor(n, dods_grid_c), d_array_var(0)
     @brief The Grid constructor.
 */
 Grid::Grid(const string &n, const string &d)
-    : Constructor(n, d, dods_grid_c), d_array_var(0)
+    : Constructor(n, d, dods_grid_c), d_is_array_set(false)
 {}
 
 /** @brief The Grid copy constructor. */
@@ -110,12 +107,7 @@ Grid::Grid(const Grid &rhs) : Constructor(rhs)
 
 Grid::~Grid()
 {
-    delete d_array_var; d_array_var = 0;
-
-    for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
-        BaseType *btp = *i ;
-        delete btp ; btp = 0;
-    }
+	//d_array_var = 0;	// Weak pointer; object will be freed by Constructor
 }
 
 BaseType *
@@ -130,22 +122,75 @@ Grid::operator=(const Grid &rhs)
     if (this == &rhs)
         return *this;
 
+    // Removed this; it makes this operator= work differently than the rest
+#if 0
     delete d_array_var; d_array_var = 0;
 
     for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
         BaseType *btp = *i ;
         delete btp ;
     }
+#endif
 
-    // this doesn't copy Constructor::d_vars so...
     dynamic_cast<Constructor &>(*this) = rhs;
 
-    // we do it in here...
     m_duplicate(rhs);
 
     return *this;
 }
 
+// FIXME transform_to_dap4 probably needs to run for side effect only.
+// drop the return BT and add variables to the D4Group that is passed
+// in instead of the DMR.
+//
+// Also need to handle the case where a Grid is part of a Structure
+BaseType *
+Grid::transform_to_dap4(D4Group *root, Constructor *container)
+{
+    BaseType *btp = array_var()->transform_to_dap4(root, container);
+    Array *coverage = static_cast<Array*>(btp);
+    if (!coverage)
+    	throw InternalErr(__FILE__, __LINE__, "Expected an Array while transforming a Grid (coverage)");
+
+	coverage->set_parent(container);
+
+	// Next find the maps; add them to the coverage and to the container,
+	// the latter only on the condition that they are not already there.
+
+	for (Map_iter i = map_begin(), e = map_end(); i != e; ++i) {
+    	btp = (*i)->transform_to_dap4(root, container);
+        Array *map = static_cast<Array*>(btp);
+        if (!map)
+        	throw InternalErr(__FILE__, __LINE__, "Expected an Array while transforming a Grid (map)");
+
+    	// map must be non-null (Grids cannot contain Grids in DAP2)
+		if (map) {
+			// Only add the map/array if it not already present; given the scoping rules
+			// for DAP2 and the assumption the DDS is valid, testing for the same name
+			// is good enough.
+			if (!root->var(map->name())) {
+				map->set_parent(container);
+				container->add_var_nocopy(map);	// this adds the array to the container
+			}
+			D4Map *dap4_map = new D4Map(map->name(), map, coverage);	// bind the 'map' to the coverage
+			coverage->maps()->add_map(dap4_map);	// bind the coverage to the map
+		}
+		else {
+			throw InternalErr(__FILE__, __LINE__,
+					"transform_to_dap4() returned a null value where there can be no Grid.");
+		}
+	}
+
+	container->add_var_nocopy(coverage);
+
+    // Since a Grid (DAP2) to a Coverage (DAP4) removes a lexical scope
+    // in favor of a set of relations, Grid::transform_to_dap4() does not
+    // return a BaseType*. Callers should assume it has correctly added
+    // stuff to the container and group.
+    return 0;
+}
+
+
 /**
  * Grid can only be used for DAP2.
  * @note This might change depending on just how complex DAP4Array becomes,
@@ -157,254 +202,6 @@ Grid::is_dap2_only_type()
     return true;
 }
 
-int
-Grid::element_count(bool leaves)
-{
-    if (!leaves)
-        return d_map_vars.size() + 1;
-    else {
-        int i = 0;
-        for (Map_iter j = d_map_vars.begin(); j != d_map_vars.end(); j++) {
-            j += (*j)->element_count(leaves);
-        }
-
-		if (!get_array())
-			throw InternalErr(__FILE__, __LINE__, "No Grid array!");
-
-        i += get_array()->element_count(leaves);
-        return i;
-    }
-}
-
-void
-Grid::set_send_p(bool state)
-{
-    d_array_var->set_send_p(state);
-
-    for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
-        (*i)->set_send_p(state);
-    }
-
-    BaseType::set_send_p(state);
-}
-
-void
-Grid::set_read_p(bool state)
-{
-    d_array_var->set_read_p(state);
-
-    for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
-        (*i)->set_read_p(state);
-    }
-
-    BaseType::set_read_p(state);
-}
-
-void
-Grid::set_in_selection(bool state)
-{
-    d_array_var->set_in_selection(state);
-
-    for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
-        (*i)->set_in_selection(state);
-    }
-
-    BaseType::set_in_selection(state);
-}
-#if 0
-unsigned int
-Grid::width(bool)
-{
-    unsigned int sz = d_array_var->width();
-
-    for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
-        sz += (*i)->width();
-    }
-
-    return sz;
-}
-#endif
-/** This version of width simply returns the same thing as width() for simple
-    types and Arrays. For Structure it returns the total size if constrained
-    is false, or the size of the elements in the current projection if true.
-
-    @param constrained If true, return the size after applying a constraint.
-    @return  The number of bytes used by the variable.
- */
-unsigned int
-Grid::width(bool constrained)
-{
-    unsigned int sz = 0;
-
-    if (constrained) {
-    	if (d_array_var->send_p())
-    		sz = d_array_var->width(constrained);
-    }
-    else {
-    	sz = d_array_var->width(constrained);
-    }
-
-    for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
-    	if (constrained) {
-    		if ((*i)->send_p())
-    			sz += (*i)->width(constrained);
-    	}
-    	else {
-    		sz += (*i)->width(constrained);
-    	}
-    }
-
-    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 (d_array_var->send_p())
-        d_array_var->intern_data(eval, dds);
-
-    for (Map_iter i = d_map_vars.begin(); i != d_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)
-{
-    DBG(cerr << "In Grid::serialize()" << endl);
-
-    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.
-    DBG(cerr << "In Grid::serialize(), before read() - read_p() returned: " << read_p() << endl);
-
-    if (!read_p())
-        read();  // read() throws Error and InternalErr
-
-    DBG(cerr << "In Grid::serialize(), past read() - read_p() returned: " << read_p() << endl);
-
-    #if EVAL
-    if (ce_eval && !eval.eval_selection(dds, dataset()))
-        return true;
-#endif
-
-    dds.timeout_off();
-
-    if (d_array_var->send_p()) {
-#ifdef CHECKSUMS
-        XDRStreamMarshaller *sm = dynamic_cast<XDRStreamMarshaller*>(&m);
-        if (sm && sm->checksums())
-            sm->reset_checksum();
-
-        d_array_var->serialize(eval, dds, m, false);
-
-        if (sm && sm->checksums())
-            sm->get_checksum();
-#else
-        DBG(cerr << "About to call Array::serialize() in Grid::serialize" << endl);
-        d_array_var->serialize(eval, dds, m, false);
-#endif
-    }
-
-    for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
-        if ((*i)->send_p()) {
-#ifdef CHECKSUMS
-            XDRStreamMarshaller *sm = dynamic_cast<XDRStreamMarshaller*>(&m);
-            if (sm && sm->checksums())
-                sm->reset_checksum();
-
-            (*i)->serialize(eval, dds, m, false);
-
-            if (sm && sm->checksums())
-                sm->get_checksum();
-#else
-            (*i)->serialize(eval, dds, m, false);
-#endif
-        }
-    }
-
-    return true;
-}
-
-bool
-Grid::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
-{
-    d_array_var->deserialize(um, dds, reuse);
-
-    for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
-        (*i)->deserialize(um, dds, reuse);
-    }
-
-    return false;
-}
-
-#if 0
-/** @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);
-}
-#endif
-
-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 (d_array_var->name() == name) {
-        if (s)
-            s->push(static_cast<BaseType *>(this));
-        return d_array_var;
-    }
-
-    for (Map_iter i = d_map_vars.begin(); i != d_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
@@ -422,30 +219,25 @@ Grid::add_var(BaseType *bt, Part part)
 {
     if (!bt)
         throw InternalErr(__FILE__, __LINE__, "Passing NULL pointer as variable to be added.");
-#if 0
-    if (bt->is_dap4_only_type())
-        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Grid.");
-#endif
-    if (part == array && d_array_var) {
+
+    if (part == array && d_is_array_set/*get_array()*/) {
       // 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!");
     }
 
+    // avoid obvious broken semantics
+    if (!dynamic_cast<Array*>(bt)) {
+      throw InternalErr(__FILE__, __LINE__, "Grid::add_var(): object is not an Array!");
+    }
+
     // 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();
+        bt_clone = bt->ptr_duplicate();
         set_array(static_cast<Array*>(bt_clone));
     }
     break;
@@ -453,37 +245,23 @@ Grid::add_var(BaseType *bt, Part part)
     case maps: {
             bt_clone = bt->ptr_duplicate();
             bt_clone->set_parent(this);
-            d_map_vars.push_back(bt_clone);
+            d_vars.push_back(bt_clone);
         }
     break;
 
     default: {
-        if (!d_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!");
-            }
+        if (!d_is_array_set/*!d_array_var*/) {
             // Add it as a copy to preserve old semantics.  This sets parent too.
-            bt_clone = p_arr->ptr_duplicate();
+            bt_clone = bt->ptr_duplicate();
             set_array(static_cast<Array*>(bt_clone));
         }
         else {
             bt_clone = bt->ptr_duplicate();
             bt_clone->set_parent(this);
-            d_map_vars.push_back(bt_clone);
+            d_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 d_vars list so we can iterate on superclass vars
-  if (bt_clone) {
-    d_vars.push_back(bt_clone);
   }
 }
 
@@ -507,60 +285,45 @@ Grid::add_var_nocopy(BaseType *bt, Part part)
 {
     if (!bt)
         throw InternalErr(__FILE__, __LINE__, "Passing NULL pointer as variable to be added.");
-#if 0
-    if (bt->is_dap4_only_type())
-        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Grid.");
-#endif
-    if (part == array && d_array_var) {
+
+    if (part == array && d_is_array_set/*get_array()*/) {
       // 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!");
     }
 
+    // avoid obvious broken semantics
+    if (!dynamic_cast<Array*>(bt)) {
+      throw InternalErr(__FILE__, __LINE__, "Grid::add_var(): object is not an Array!");
+    }
+
     bt->set_parent(this);
 
     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!");
-        }
         set_array(static_cast<Array*>(bt));
     }
     break;
 
     case maps: {
+    	// FIXME Why is this commented out?
             //bt->set_parent(this);
-            d_map_vars.push_back(bt);
+            d_vars.push_back(bt);
         }
     break;
 
     default: {
-        if (!d_array_var) {
+        if (!d_is_array_set/*!get_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!");
-            }
             set_array(static_cast<Array*>(bt));
         }
         else {
-            d_map_vars.push_back(bt);
+            d_vars.push_back(bt);
         }
     }
     break;
-  }// switch
-
-  // if we get here without exception, add the cloned object to the superclass variable iterator
-  // mjohnson 10 Sep 2009
-  // Add it to the superclass d_vars list so we can iterate on superclass vars
-  if (bt) {
-    d_vars.push_back(bt);
   }
 }
 
@@ -570,25 +333,50 @@ Grid::add_var_nocopy(BaseType *bt, Part part)
  * is made).
  * If there already exists an array portion, the old
  * one will be deleted to avoid leaks.
+ *
+ * @note This code has been modified to use a new storage for
+ * the Grid's variables (the storage defined by Constructor).
+ *
  * @param p_new_arr  the object to store as the array
  *                   part of the grid.
  */
-void
-Grid::set_array(Array* p_new_arr)
+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 == d_array_var) {
-      return;
-   }
-  // clean out any old array
-  delete d_array_var; d_array_var = 0;
-  // Set the new, with parent
-  d_array_var = p_new_arr;
-  d_array_var->set_parent(this);
+	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 == get_array()) {
+		return;
+	}
+
+	p_new_arr->set_parent(this);
+
+	// Three cases: 1. There are no variables set for this grid at all
+	// 2. There are maps but no array
+	// 3. There is already an array set (and maybe maps).
+	// NB: d_array_var is a weak pointer to the Grid's Array
+	if (d_vars.size() == 0) {
+		d_vars.push_back(p_new_arr);
+	}
+	else if (!d_is_array_set/*!d_array_var*/) {
+		d_vars.insert(d_vars.begin(), p_new_arr);
+	}
+	else {
+		// clean out old array
+		delete get_array();
+		d_vars[0] = p_new_arr;
+	}
+
+	d_is_array_set = true;
+#if 0
+	// store the array pointer locally
+	d_array_var = p_new_arr;
+
+	// Set the  parent
+	d_array_var->set_parent(this);
+#endif
 }
 
 /**
@@ -622,16 +410,13 @@ 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 0
-  if (p_new_map->is_dap4_only_type())
-      throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Grid.");
-#endif
+
   if (add_as_copy)
     p_new_map = static_cast<Array*>(p_new_map->ptr_duplicate());
 
   p_new_map->set_parent(this);
-  d_map_vars.push_back(p_new_map);
-  d_vars.push_back(p_new_map); // allow superclass iter to work as well.
+
+  d_vars.push_back(p_new_map);
 
   // return the one that got put into the Grid.
   return p_new_map;
@@ -658,11 +443,9 @@ Grid::prepend_map(Array* p_new_map, bool add_copy)
     }
 
   p_new_map->set_parent(this);
-  d_map_vars.insert(d_map_vars.begin(), p_new_map);
-  d_vars.insert(d_vars.begin(), p_new_map); // allow superclass iter to work as well.
+  d_vars.insert(map_begin(), p_new_map);
 
-   // return the one that got put into the Grid.
-   return p_new_map;
+  return p_new_map;
 }
 
 /** @brief Returns the Grid Array.
@@ -671,7 +454,15 @@ Grid::prepend_map(Array* p_new_map, bool add_copy)
 BaseType *
 Grid::array_var()
 {
-    return d_array_var;
+    //return d_array_var;
+	// FIXME Should really test that the array has not be set; maps might be added first. jhrg 5/9/13
+#if 0
+	if (d_array_var)
+		cerr << "In array_var(), d_array_var holds a " << d_array_var->type_name() << endl;
+	else
+		cerr << "In array_var(), d_array_var is null" << endl;
+#endif
+	return d_is_array_set /*d_vars.size() > 0*/ ? *d_vars.begin() : 0;
 }
 
 /** @brief Returns the Grid Array.
@@ -680,18 +471,18 @@ Grid::array_var()
 Array *
 Grid::get_array()
 {
-    Array *a = dynamic_cast<Array*>(d_array_var);
-    if (a)
-        return a;
-    else
-        throw InternalErr(__FILE__, __LINE__, "bad Cast");
+    return dynamic_cast<Array*>(array_var());
 }
 
 /** @brief Returns an iterator referencing the first Map vector. */
 Grid::Map_iter
 Grid::map_begin()
 {
-    return d_map_vars.begin() ;
+    // The maps are stored in the second and subsequent elements of the
+    // d_var vector<BaseType*> of Constructor _unless_ the Array part
+    // has yet to be set. In the latter case, there are only maps in
+    // d_vars
+    return d_is_array_set/*(d_array_var != 0)*/ ? d_vars.begin() + 1: d_vars.begin();
 }
 
 /** Returns an iterator referencing the end of the list of Map vectors.
@@ -699,14 +490,16 @@ Grid::map_begin()
 Grid::Map_iter
 Grid::map_end()
 {
-    return d_map_vars.end() ;
+    return d_vars.end();
 }
 
 /** @brief Returns an iterator referencing the first Map vector. */
 Grid::Map_riter
 Grid::map_rbegin()
 {
-    return d_map_vars.rbegin() ;
+    // see above
+    // return d_is_array_set/*(d_array_var != 0)*/ ? d_vars.rbegin() + 1: d_vars.rbegin();
+    return d_vars.rbegin();
 }
 
 /** Returns an iterator referencing the end of the list of Map vectors.
@@ -714,7 +507,7 @@ Grid::map_rbegin()
 Grid::Map_riter
 Grid::map_rend()
 {
-    return d_map_vars.rend() ;
+    return d_is_array_set ? d_vars.rend() - 1: d_vars.rend();
 }
 
 /** Return the iterator for the \e ith map.
@@ -723,7 +516,8 @@ Grid::map_rend()
 Grid::Map_iter
 Grid::get_map_iter(int i)
 {
-    return d_map_vars.begin() + i;
+    // return map_begin() + i;
+    return d_is_array_set ? map_begin() + 1 + i : map_begin() + i;
 }
 
 /** Returns the number of components in the Grid object.  This is
@@ -747,16 +541,16 @@ Grid::components(bool constrained)
     int comp;
 
     if (constrained) {
-        comp = d_array_var->send_p() ? 1 : 0;
+        comp = get_array()->send_p() ? 1 : 0;
 
-        for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
+        for (Map_iter i = map_begin(); i != map_end(); i++) {
             if ((*i)->send_p()) {
                 comp++;
             }
         }
     }
     else {
-        comp = 1 + d_map_vars.size();
+        comp = d_vars.size();
     }
 
     return comp;
@@ -764,36 +558,34 @@ Grid::components(bool constrained)
 
 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++;
+	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
@@ -823,7 +615,7 @@ Grid::projection_yields_grid()
     // projected dimension in the Array component, there is a matching Map
     // vector, then the Grid is valid.
     bool valid = true;
-    Array *a = (Array *)d_array_var;
+    Array *a = get_array();
 
     // Don't bother checking if the Array component is not included.
     if (!a->send_p())
@@ -833,7 +625,7 @@ Grid::projection_yields_grid()
     // 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;
+    	return false;
 
     Array::Dim_iter d = a->dim_begin() ;
     Map_iter m = map_begin() ;
@@ -862,7 +654,7 @@ Grid::projection_yields_grid()
 void
 Grid::clear_constraint()
 {
-    dynamic_cast<Array&>(*d_array_var).clear_constraint();
+    get_array()->clear_constraint();
     for (Map_iter m = map_begin(); m != map_end(); ++m)
         dynamic_cast<Array&>(*(*m)).clear_constraint();
 }
@@ -887,10 +679,10 @@ Grid::print_decl(ostream &out, string space, bool print_semi,
     if (constrained && !projection_yields_grid()) {
 	out << space << "Structure {\n" ;
 
-        d_array_var->print_decl(out, space + "    ", true, constraint_info,
+        get_array()->print_decl(out, space + "    ", true, constraint_info,
                                constrained);
 
-        for (Map_citer i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
+        for (Map_citer i = map_begin(); i != map_end(); i++) {
             (*i)->print_decl(out, space + "    ", true,
                              constraint_info, constrained);
         }
@@ -903,11 +695,11 @@ Grid::print_decl(ostream &out, string space, bool print_semi,
 	out << space << type_name() << " {\n" ;
 
 	out << space << "  Array:\n" ;
-        d_array_var->print_decl(out, space + "    ", true, constraint_info,
+        get_array()->print_decl(out, space + "    ", true, constraint_info,
                                constrained);
 
 	out << space << "  Maps:\n" ;
-        for (Map_citer i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
+        for (Map_citer i = map_begin(); i != map_end(); i++) {
             (*i)->print_decl(out, space + "    ", true,
                              constraint_info, constrained);
         }
@@ -1041,11 +833,10 @@ Grid::print_val(ostream &out, string space, bool print_decl_p)
 	out << "{  Array: " ;
     else
 	out << "{" ;
-    d_array_var->print_val(out, "", false);
+    get_array()->print_val(out, "", false);
     if (pyg || !send_p())
 	out << "  Maps: " ;
-    for (Map_citer i = d_map_vars.begin(); i != d_map_vars.end();
-         i++, (void)(i != d_map_vars.end() && out << ", ")) {
+    for (Map_citer i = map_begin(); i != map_end(); i++, (void)(i != map_end() && out << ", ")) {
         (*i)->print_val(out, "", false);
     }
     out << " }" ;
@@ -1068,18 +859,18 @@ Grid::check_semantics(string &msg, bool all)
 
     msg = "";
 
-    if (!d_array_var) {
+    if (!get_array()) {
         msg += "Null grid base array in `" + name() + "'\n";
         return false;
     }
 
     // Is it an array?
-    if (d_array_var->type() != dods_array_c) {
-        msg += "Grid `" + name() + "'s' member `" + d_array_var->name() + "' must be an array\n";
+    if (get_array()->type() != dods_array_c) {
+        msg += "Grid `" + name() + "'s' member `" + get_array()->name() + "' must be an array\n";
         return false;
     }
 
-    Array *av = (Array *)d_array_var; // past test above, must be an array
+    Array *av = (Array *)get_array(); // past test above, must be an array
 
     // Array must be of a simple_type.
     if (!av->var()->is_simple_type()) {
@@ -1088,7 +879,7 @@ Grid::check_semantics(string &msg, bool all)
     }
 
     // enough maps?
-    if ((unsigned)d_map_vars.size() != av->dimensions()) {
+    if ((unsigned)d_vars.size()-1 != 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;
@@ -1096,8 +887,7 @@ Grid::check_semantics(string &msg, bool all)
 
     const string array_var_name = av->name();
     Array::Dim_iter asi = av->dim_begin() ;
-    for (Map_iter mvi = d_map_vars.begin();
-         mvi != d_map_vars.end(); mvi++, asi++) {
+    for (Map_iter mvi = map_begin(); mvi != map_end(); mvi++, asi++) {
 
         BaseType *mv = *mvi;
 
@@ -1131,15 +921,15 @@ Grid::check_semantics(string &msg, bool all)
         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 += d_array_var->name() + "'s' cooresponding dimension\n";
+            msg += get_array()->name() + "'s' cooresponding dimension\n";
             return false;
         }
     }
 
     if (all) {
-        if (!d_array_var->check_semantics(msg, true))
+        if (!get_array()->check_semantics(msg, true))
             return false;
-        for (Map_iter mvi = d_map_vars.begin(); mvi != d_map_vars.end(); mvi++) {
+        for (Map_iter mvi = map_begin(); mvi != map_end(); mvi++) {
             if (!(*mvi)->check_semantics(msg, true)) {
                 return false;
             }
@@ -1164,23 +954,7 @@ Grid::dump(ostream &strm) const
     << (void *)this << ")" << endl ;
     DapIndent::Indent() ;
     Constructor::dump(strm) ;
-    if (d_array_var) {
-        strm << DapIndent::LMarg << "array var: " << endl ;
-        DapIndent::Indent() ;
-        d_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 = d_map_vars.begin() ;
-    Map_citer ie = d_map_vars.end() ;
-    for (; i != ie; i++) {
-        (*i)->dump(strm) ;
-    }
-    DapIndent::UnIndent() ;
+
     DapIndent::UnIndent() ;
 }
 
diff --git a/Grid.h b/Grid.h
index 813543a..c26db92 100644
--- a/Grid.h
+++ b/Grid.h
@@ -42,8 +42,6 @@
 
 #include <vector>
 
-//#include "Pix.h"
-
 #ifndef _basetype_h
 #include "BaseType.h"
 #endif
@@ -63,6 +61,9 @@
 namespace libdap
 {
 
+class D4Grup;
+class XMLWriter;
+
 /** 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
@@ -121,8 +122,8 @@ namespace libdap
 class Grid: public Constructor
 {
 private:
-    BaseType *d_array_var;
-    std::vector<BaseType *> d_map_vars;
+    //BaseType *d_array_var;	// weak pointer to the
+    bool d_is_array_set;
 
 protected: // subclasses need access [mjohnson 11 nov 2009]
     void m_duplicate(const Grid &s);
@@ -142,16 +143,9 @@ public:
     Grid &operator=(const Grid &rhs);
     virtual BaseType *ptr_duplicate();
 
-    virtual bool is_dap2_only_type();
-
-    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 *transform_to_dap4(D4Group *root, Constructor *container);
 
-    virtual BaseType *var(const string &n, bool exact = true, btp_stack *s = 0);
-    virtual BaseType *var(const string &n, btp_stack &s);
+    virtual bool is_dap2_only_type();
 
     virtual void add_var(BaseType *bt, Part part);
     virtual void add_var_nocopy(BaseType *bt, Part part);
@@ -163,24 +157,14 @@ public:
     BaseType *array_var();
     Array *get_array();
 
-    virtual unsigned int width(bool constrained = false);
-#if 0
-    virtual unsigned int width(bool constrained);
-#endif
+    // virtual unsigned int width(bool constrained = false);
+
     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);
-#if 0
-    virtual unsigned int val2buf(void *buf, bool reuse = false);
-    virtual unsigned int buf2val(void **val);
-#endif
-
     virtual void print_decl(ostream &out, string space = "    ",
                             bool print_semi = true,
                             bool constraint_info = false,
diff --git a/HTTPCache.cc b/HTTPCache.cc
index d852353..c4279ad 100644
--- a/HTTPCache.cc
+++ b/HTTPCache.cc
@@ -152,24 +152,21 @@ HTTPCache::instance(const string &cache_root, bool force)
             // 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);
+            EventHandler *old_eh = SignalHandler::instance()->register_handler(SIGINT, new HTTPCacheInterruptHandler, true);
             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);
+            old_eh = SignalHandler::instance()->register_handler(SIGPIPE, new HTTPCacheInterruptHandler, true);
             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);
+            old_eh = SignalHandler::instance()->register_handler(SIGTERM, new HTTPCacheInterruptHandler, true);
             if (old_eh) {
                 SignalHandler::instance()->register_handler(SIGTERM, old_eh);
                 throw SignalHandlerRegisteredErr(
@@ -197,10 +194,16 @@ 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;
+
+        //Now remove the signal handlers
+        delete SignalHandler::instance()->remove_handler(SIGINT);
+        delete SignalHandler::instance()->remove_handler(SIGPIPE);
+        delete SignalHandler::instance()->remove_handler(SIGTERM);
     }
 
     DBG(cerr << "Exiting delete_instance()" << endl);
@@ -477,7 +480,7 @@ bool HTTPCache::get_single_user_lock(bool force)
 	return true;
     }
 
-    cerr << "locked_open_file is true" << endl;
+    DBG(cerr << "locked_open_file is true" << endl);
     return false;
 }
 
diff --git a/HTTPCache.h b/HTTPCache.h
index f6f9d47..4a0861d 100644
--- a/HTTPCache.h
+++ b/HTTPCache.h
@@ -167,6 +167,8 @@ private:
     static HTTPCache *_instance;
 
     friend class HTTPCacheTest; // Unit tests
+    friend class HTTPConnectTest;
+
     friend class HTTPCacheInterruptHandler;
 
     // Private methods
diff --git a/HTTPCacheResponse.h b/HTTPCacheResponse.h
index 12c243d..17bc4c6 100644
--- a/HTTPCacheResponse.h
+++ b/HTTPCacheResponse.h
@@ -49,14 +49,9 @@ private:
 protected:
     /** @name Suppressed default methods */
     //@{
-    HTTPCacheResponse()
-    {}
-    HTTPCacheResponse(const HTTPCacheResponse &rs) : HTTPResponse(rs)
-    {}
-    HTTPCacheResponse &operator=(const HTTPCacheResponse &)
-    {
-        throw InternalErr(__FILE__, __LINE__, "Unimplemented assignment");
-    }
+    HTTPCacheResponse();
+    HTTPCacheResponse(const HTTPCacheResponse &rs);
+    HTTPCacheResponse &operator=(const HTTPCacheResponse &);
     //@}
 
 public:
diff --git a/HTTPConnect.cc b/HTTPConnect.cc
index 7072cca..68663ff 100644
--- a/HTTPConnect.cc
+++ b/HTTPConnect.cc
@@ -41,6 +41,7 @@
 #include <functional>
 #include <algorithm>
 #include <sstream>
+#include <fstream>
 #include <iterator>
 #include <cstdlib>
 #include <cstring>
@@ -54,6 +55,7 @@
 
 #include "debug.h"
 #include "mime_util.h"
+#include "media_types.h"
 #include "GNURegex.h"
 #include "HTTPCache.h"
 #include "HTTPConnect.h"
@@ -127,6 +129,42 @@ http_status_to_string(int status)
         return string("Unknown Error: This indicates a problem with libdap++.\nPlease report this to support at opendap.org.");
 }
 
+static ObjectType
+determine_object_type(const string &header_value)
+{
+    // DAP4 Data: application/vnd.opendap.dap4.data
+    // DAP4 DMR: application/vnd.opendap.dap4.dataset-metadata+xml
+
+    string::size_type plus = header_value.find('+');
+    string base_type;
+    string type_extension = "";
+    if (plus != string::npos) {
+        base_type= header_value.substr(0, plus);
+        type_extension = header_value.substr(plus+1);
+    }
+    else
+        base_type = header_value;
+
+    if (base_type == DMR_Content_Type
+    	|| (base_type.find("application/") != string::npos
+    		&& base_type.find("dap4.dataset-metadata") != string::npos)) {
+        if (type_extension == "xml")
+            return dap4_dmr;
+        else
+            return unknown_type;
+    }
+    else if (base_type == DAP4_DATA_Content_Type
+    		|| (base_type.find("application/") != string::npos
+    			&& base_type.find("dap4.data") != string::npos)) {
+        return dap4_data;
+    }
+    else if (header_value.find("text/html") != string::npos) {
+        return web_error;
+    }
+    else
+        return unknown_type;
+}
+
 /** 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. */
@@ -146,38 +184,36 @@ public:
     {
         string name, value;
         parse_mime_header(line, name, value);
-        if (name == "content-description") {
-            DBG2(cerr << name << ": " << value << endl);
-            type = get_description_type(value);
+
+        DBG2(cerr << name << ": " << value << endl);
+
+        // Content-Type is used to determine the content of DAP4 responses, but allow the
+        // Content-Description header to override CT o preserve operation with DAP2 servers.
+        // jhrg 11/12/13
+        if (type == unknown_type && name == "content-type") {
+            type = determine_object_type(value); // see above
+        }
+        if (name == "content-description" && !(type == dap4_dmr || type == dap4_data || type == dap4_error)) {
+            type = get_description_type(value); // defined in mime_util.cc
         }
         // 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()
@@ -203,10 +239,9 @@ public:
 /** 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
+    without using it itself. I use that to pass in a pointer to a vector
+    of strings so that there's some place to
+    dump the headers. 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.
@@ -330,14 +365,14 @@ HTTPConnect::www_lib_init()
     curl_easy_setopt(d_curl, CURLOPT_MAXREDIRS, 5);
 
     // If the user turns off SSL validation...
-    if (!d_rcr->get_validate_ssl() == 0) {
+    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
+    // expiration date) here so that session-based SSO systems will work as
     // expected.
     if (!d_cookie_jar.empty()) {
 	DBG(cerr << "Setting the cookie jar to: " << d_cookie_jar << endl);
@@ -391,9 +426,7 @@ public:
     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)
+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());
 
@@ -405,10 +438,10 @@ HTTPConnect::read_url(const string &url, FILE *stream,
     //  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_WRITEDATA, stream);
     curl_easy_setopt(d_curl, CURLOPT_WRITEFUNCTION, &fwrite);
 #else
-    curl_easy_setopt(d_curl, CURLOPT_FILE, stream);
+    curl_easy_setopt(d_curl, CURLOPT_WRITEDATA, stream);
 #endif
 
     DBG(copy(d_request_headers.begin(), d_request_headers.end(),
@@ -465,6 +498,13 @@ HTTPConnect::read_url(const string &url, FILE *stream,
     if (res != 0)
         throw Error(d_error_buffer);
 
+    char *ct_ptr = 0;
+    res = curl_easy_getinfo(d_curl, CURLINFO_CONTENT_TYPE, &ct_ptr);
+    if (res == CURLE_OK && ct_ptr)
+        d_content_type = ct_ptr;
+    else
+        d_content_type = "";
+
     return status;
 }
 
@@ -501,10 +541,8 @@ HTTPConnect::url_uses_no_proxy_for(const string &url) throw()
     @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)
+HTTPConnect::HTTPConnect(RCReader *rcr, bool use_cpp) : d_username(""), d_password(""), d_cookie_jar(""),
+		d_dap_client_protocol_major(2),	d_dap_client_protocol_minor(0), d_use_cpp_streams(use_cpp)
 
 {
     d_accept_deflate = rcr->get_deflate();
@@ -553,6 +591,14 @@ HTTPConnect::~HTTPConnect()
     DBG2(cerr << "Leaving the HTTPConnect dtor" << endl);
 }
 
+/** 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; }
+};
+
 /** 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
@@ -574,7 +620,7 @@ HTTPConnect::fetch_url(const string &url)
 
     HTTPResponse *stream;
 
-    if (d_http_cache && d_http_cache->is_cache_enabled()) {
+    if (/*d_http_cache && d_http_cache->*/is_cache_enabled()) {
         stream = caching_fetch_url(url);
     }
     else {
@@ -582,18 +628,24 @@ HTTPConnect::fetch_url(const string &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();
+	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());
+    // An apparent quirk of libcurl is that it does not pass the Content-type
+    // header to the callback used to save them, but check and add it from the
+    // saved state variable only if it's not there (without this a test failed
+    // in HTTPCacheTest). jhrg 11/12/13
+    if (!d_content_type.empty() && find_if(stream->get_headers()->begin(), stream->get_headers()->end(),
+    									   HeaderMatch("Content-Type:")) == stream->get_headers()->end())
+        stream->get_headers()->push_back("Content-Type: " + d_content_type);
+    parser = for_each(stream->get_headers()->begin(), stream->get_headers()->end(), ParseHeader());
 
 #ifdef HTTP_TRACE
     cout << endl << endl;
@@ -602,14 +654,19 @@ HTTPConnect::fetch_url(const string &url)
     // 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;
+    	delete stream;
         return fetch_url(parser.get_location());
     }
 
-    stream->set_type(parser.get_object_type());
+    stream->set_type(parser.get_object_type()); // uses the value of content-description
+
     stream->set_version(parser.get_server());
     stream->set_protocol(parser.get_protocol());
 
+    if (d_use_cpp_streams) {
+    	stream->transform_to_cpp();
+    }
+
     return stream;
 }
 
@@ -622,7 +679,7 @@ HTTPConnect::fetch_url(const string &url)
 // 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
+// file. 9/21/07 jhrg Updated to use strings, other misc changes. 3/22/11
 static string
 get_tempfile_template(const string &file_template)
 {
@@ -706,7 +763,7 @@ valid_temp_directory:
     @exception InternalErr thrown if the FILE* could not be opened. */
 
 string
-get_temp_file(FILE *&stream) throw(InternalErr)
+get_temp_file(FILE *&stream) throw(Error)
 {
     string dods_temp = get_tempfile_template((string)"dodsXXXXXX");
 
@@ -725,17 +782,19 @@ get_temp_file(FILE *&stream) throw(InternalErr)
     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 + ")");
-    }
+    if (!stream)
+    	throw Error("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(). */
+
+/**
+ * close temporary files - used here and in ~HTTPResponse
+ * @param s
+ * @param name
+ */
 void
 close_temp(FILE *s, const string &name)
 {
@@ -875,33 +934,43 @@ HTTPConnect::caching_fetch_url(const string &url)
 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; resp_hdrs = 0;
-            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);
+	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; resp_hdrs = 0;
+			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;
+	}
+
+#if 0
+	if (d_use_cpp_streams) {
+		fclose(stream);
+		fstream *in = new fstream(dods_temp.c_str(), ios::in|ios::binary);
+		return new HTTPResponse(in, status, resp_hdrs, dods_temp);
+	}
+	else {
+#endif
+	rewind(stream);
+	return new HTTPResponse(stream, status, resp_hdrs, dods_temp);
+#if 0
+}
+#endif
 }
 
 /** Set the <em>accept deflate</em> property. If true, the DAP client
@@ -936,14 +1005,6 @@ HTTPConnect::set_accept_deflate(bool deflate)
     }
 }
 
-/** 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
diff --git a/HTTPConnect.h b/HTTPConnect.h
index c04972f..e3b6f99 100644
--- a/HTTPConnect.h
+++ b/HTTPConnect.h
@@ -64,14 +64,8 @@ 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.
+    headers used by DAP 2.0 and extract their values. The body of the
+    response is made available using a FILE pointer.
 
     @author jhrg */
 
@@ -83,6 +77,7 @@ private:
     HTTPCache *d_http_cache;
 
     char d_error_buffer[CURL_ERROR_SIZE]; // A human-readable message.
+    std::string d_content_type; // apparently read by libcurl; this is valid only after curl_easy_perform()
 
     bool d_accept_deflate;
 
@@ -97,10 +92,12 @@ private:
     int d_dap_client_protocol_major;
     int d_dap_client_protocol_minor;
 
+    bool d_use_cpp_streams;	// Build HTTPResponse objects using fstream and not FILE*
+
     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);
 
@@ -120,19 +117,13 @@ 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");
-	}
+    HTTPConnect();
+	HTTPConnect(const HTTPConnect &);
+	HTTPConnect &operator=(const HTTPConnect &);
     //@}
 
 public:
-    HTTPConnect(RCReader *rcr);
+    HTTPConnect(RCReader *rcr, bool use_cpp = false);
 
     virtual ~HTTPConnect();
 
@@ -140,33 +131,29 @@ public:
     void set_accept_deflate(bool defalte);
     void set_xdap_protocol(int major, int minor);
 
+    bool use_cpp_streams() const { return d_use_cpp_streams; }
+    void set_use_cpp_streams(bool use_cpp_streams) { d_use_cpp_streams = use_cpp_streams; }
+
     /** 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;
-    }
+    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)
-    {
+    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;
-    }
+    bool is_cache_enabled() { return (d_http_cache) ? d_http_cache->is_cache_enabled() : false; }
 
     HTTPResponse *fetch_url(const string &url);
 };
diff --git a/HTTPResponse.h b/HTTPResponse.h
index 3449463..978b246 100644
--- a/HTTPResponse.h
+++ b/HTTPResponse.h
@@ -26,55 +26,45 @@
 #ifndef http_response_h
 #define http_response_h
 
+#include <unistd.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 "util.h"
 #include "debug.h"
-#endif
 
 namespace libdap
 {
 
-extern int dods_keep_temps; // defined in HTTPConnect.cc
-
+// defined in HTTPConnect.cc
+extern int dods_keep_temps;
 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
+    @todo Maybe refactor so that the header parsing code is here 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
+    std::vector<std::string> *d_headers; // Response headers
+    std::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");
-    }
+    HTTPResponse();
+    HTTPResponse(const HTTPResponse &rs);
+    HTTPResponse &operator=(const HTTPResponse &);
     //@}
 
 public:
@@ -94,7 +84,25 @@ public:
     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)
+    HTTPResponse(FILE *s, int status, std::vector<std::string> *h, const std::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);
+    }
+
+    /**
+     * @brief Build a HTTPResponse using a cpp fstream
+     * When working with DAP4 responses, use C++ streams for I/0.
+     * @todo Decide on how the temp files fit into DAP4
+     * @param s
+     * @param status
+     * @param h
+     * @param temp_file
+     */
+    HTTPResponse(std::fstream *s, int status, std::vector<std::string> *h, const std::string &temp_file)
             : Response(s, status), d_headers(h), d_file(temp_file)
     {
         DBG(cerr << "Headers: " << endl);
@@ -110,38 +118,51 @@ public:
     {
         DBG(cerr << "Freeing HTTPConnect resources (" + d_file + ")... ");
 
+        // This can always be done - if the cpp_stream is null, delete has no effect;
+        // if non-null in this class it was allocated in HTTPConnect::plain_fetch_url
+        // (or caching_fetch_url when that's implemented)
+		delete get_cpp_stream();
+		set_cpp_stream(0);
+
         if (!dods_keep_temps && !d_file.empty()) {
-            close_temp(get_stream(), d_file);
-            set_stream(0);
+			if (get_stream()) {
+				close_temp(get_stream(), d_file);
+				set_stream(0);
+			}
+			else {
+				long res = unlink(d_file.c_str());
+				if (res != 0) throw InternalErr(__FILE__, __LINE__, "!FAIL! " + long_to_string(res));
+			}
         }
 
-        delete d_headers; d_headers = 0;
+        delete d_headers;
 
         DBGN(cerr << endl);
     }
+
+    /**
+     * Build a new HTTPResponse object that works with C++ streams. Assume that
+     * the FILE* references a disk file.
+     * @return
+     */
+    void transform_to_cpp() {
+    	// ~Response() will take care of closing the FILE*. A better version of this
+    	// code would not leave the FILE* open when it's not needed, but this implementation
+    	// can use the existing HTTPConnect and HTTPCache software with very minimal
+    	// (or no) modification. jhrg 11/8/13
+    	set_cpp_stream(new std::fstream(d_file.c_str(), std::ios::in|std::ios::binary));
+    }
+
     /** @name Accessors */
     //@{
-    virtual vector<string> *get_headers() const
-    {
-        return d_headers;
-    }
-    virtual string get_file() const
-    {
-        return d_file;
-    }
+    virtual std::vector<std::string> *get_headers() const { return d_headers; }
+    virtual std::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;
-    }
+    virtual void set_headers(std::vector<std::string> *h) { d_headers = h; }
+    virtual void set_file(const std::string &n) { d_file = n; }
     //@}
 };
 
diff --git a/INSTALL b/INSTALL
index b432a26..e8f3ad3 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,5 @@
 
-Updated for version 3.12.0 of the OPeNDAP DAP 3.4 library software.
+Updated for version 3.13.3 of the OPeNDAP DAP 3.5 library software.
 
 Installing the DAP2/3.x library
 
@@ -71,7 +71,7 @@ AFTER INSTALLING
 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
+    autoconf 2.61 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 2.4
@@ -79,11 +79,8 @@ REQUIREMENTS
 
   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.
+    library. You must have libcurl version 7.19.0 or newer and libxml2 2.7.0
+    or newer.
 
   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.,
@@ -94,19 +91,22 @@ REQUIREMENTS
     
 	'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 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 and OSX's compiler bundled
+    with OSX 10.9 (Apple LLVM version 5.1 (clang-503.0.40) (based on
+    LLVM 3.4svn). 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
+    need bison 2.4 and flex 3.7.9. 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.
diff --git a/Int16.cc b/Int16.cc
index ad46358..cf2eb44 100644
--- a/Int16.cc
+++ b/Int16.cc
@@ -51,11 +51,14 @@
 #include "Str.h"
 #include "Url.h"
 
-
+#include "DDS.h"
 #include "Marshaller.h"
 #include "UnMarshaller.h"
 
-#include "DDS.h"
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
 #include "util.h"
 #include "parser.h"
 #include "Operators.h"
@@ -72,7 +75,7 @@ namespace libdap {
 
     @param n A string containing the name of the variable to be created.
 */
-Int16::Int16(const string &n) : BaseType(n, dods_int16_c)
+Int16::Int16(const string &n) : BaseType(n, dods_int16_c), d_buf(0)
 {}
 
 /** The Int16 server-side constructor accepts the name of the variable and
@@ -82,7 +85,7 @@ Int16::Int16(const string &n) : BaseType(n, dods_int16_c)
     @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 string &n, const string &d) : BaseType(n, d, dods_int16_c), d_buf(0)
 {}
 
 Int16::Int16(const Int16 &copy_from) : BaseType(copy_from)
@@ -110,24 +113,21 @@ Int16::operator=(const Int16 &rhs)
 }
 
 unsigned int
-Int16::width(bool)
+Int16::width(bool) const
 {
     return sizeof(dods_int16);
 }
 
 bool
-Int16::serialize(ConstraintEvaluator &eval, DDS &dds,
-                 Marshaller &m, bool ce_eval)
+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();
 
@@ -144,6 +144,35 @@ Int16::deserialize(UnMarshaller &um, DDS *, bool)
     return false;
 }
 
+void
+Int16::compute_checksum(Crc32 &checksum)
+{
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
+
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+Int16::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+    m.put_int16( d_buf ) ;
+}
+
+void
+Int16::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+    um.get_int16( d_buf ) ;
+}
+
 unsigned int
 Int16::val2buf(void *val, bool)
 {
diff --git a/Int16.h b/Int16.h
index f26f8b3..e26de1b 100644
--- a/Int16.h
+++ b/Int16.h
@@ -52,6 +52,8 @@
 namespace libdap
 {
 
+class DMR;
+
 /** @brief Holds a 16-bit signed integer value. */
 
 class Int16: public BaseType
@@ -70,13 +72,17 @@ public:
     Int16 &operator=(const Int16 &rhs);
 
     virtual BaseType *ptr_duplicate();
+    virtual unsigned int width(bool constrained = false) const;
 
-    virtual unsigned int width(bool constrained = false);
-
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true);
+    // DAP2
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval = true);
     virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
 
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
     virtual unsigned int val2buf(void *val, bool reuse = false);
     virtual unsigned int buf2val(void **val);
 
diff --git a/Int32.cc b/Int32.cc
index ca5a416..d777f3f 100644
--- a/Int32.cc
+++ b/Int32.cc
@@ -51,11 +51,14 @@
 #include "Str.h"
 #include "Url.h"
 
-
 #include "DDS.h"
 #include "Marshaller.h"
 #include "UnMarshaller.h"
 
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
 #include "util.h"
 #include "parser.h"
 #include "Operators.h"
@@ -76,8 +79,7 @@ namespace libdap {
     @param n A string containing the name of the variable to be
     created.
 */
-Int32::Int32(const string &n)
-        : BaseType(n, dods_int32_c)
+Int32::Int32(const string &n) : BaseType(n, dods_int32_c), d_buf(0)
 {}
 
 /** The Int32 server-side constructor accepts the name of the variable and
@@ -87,8 +89,7 @@ Int32::Int32(const string &n)
     @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 string &n, const string &d) : BaseType(n, d, dods_int32_c), d_buf(0)
 {}
 
 Int32::Int32(const Int32 &copy_from) : BaseType(copy_from)
@@ -121,7 +122,7 @@ Int32::operator=(const Int32 &rhs)
 }
 
 unsigned int
-Int32::width(bool)
+Int32::width(bool) const
 {
     return sizeof(dods_int32);
 }
@@ -135,10 +136,8 @@ Int32::serialize(ConstraintEvaluator &eval, DDS &dds,
     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();
 
@@ -155,6 +154,35 @@ Int32::deserialize(UnMarshaller &um, DDS *, bool)
     return false;
 }
 
+void
+Int32::compute_checksum(Crc32 &checksum)
+{
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
+
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+Int32::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+    m.put_int32( d_buf ) ;
+}
+
+void
+Int32::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+    um.get_int32( d_buf ) ;
+}
+
 unsigned int
 Int32::val2buf(void *val, bool)
 {
@@ -224,8 +252,6 @@ Int32::print_val(ostream &out, string space, bool print_decl_p)
 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
diff --git a/Int32.h b/Int32.h
index 41183c9..c8c6bae 100644
--- a/Int32.h
+++ b/Int32.h
@@ -54,6 +54,7 @@
 namespace libdap
 {
 
+class DMR;
 class ConstraintEvaluator;
 
 /** @brief Holds a 32-bit signed integer.
@@ -77,13 +78,17 @@ public:
     virtual ~Int32();
 
     virtual BaseType *ptr_duplicate();
+    virtual unsigned int width(bool constrained = false) const;
 
-    virtual unsigned int width(bool constrained = false);
-
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true);
+    //DAP2
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval = true);
     virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
 
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
     virtual unsigned int val2buf(void *val, bool reuse = false);
     virtual unsigned int buf2val(void **val);
 
diff --git a/Int64.cc b/Int64.cc
index b0a73e8..ae4aebd 100644
--- a/Int64.cc
+++ b/Int64.cc
@@ -59,10 +59,10 @@
 #include "Grid.h"
 #endif
 
-#include "DAP4StreamMarshaller.h"
-#include "DAP4StreamUnMarshaller.h"
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
 
-#include "DDS.h"
 #include "util.h"
 #include "parser.h"
 #include "Operators.h"
@@ -82,7 +82,7 @@ namespace libdap {
     @param n A string containing the name of the variable to be
     created.
 */
-Int64::Int64(const string &n) : BaseType(n, dods_int64_c)
+Int64::Int64(const string &n) : BaseType(n, dods_int64_c, true /*is_dap4*/), d_buf(0)
 {}
 
 /** The Int64 server-side constructor accepts the name of the variable and
@@ -92,7 +92,7 @@ Int64::Int64(const string &n) : BaseType(n, dods_int64_c)
     @param d A string containing the name of the dataset from which this
     variable is created
 */
-Int64::Int64(const string &n, const string &d) : BaseType(n, d, dods_int64_c)
+Int64::Int64(const string &n, const string &d) : BaseType(n, d, dods_int64_c, true /*is_dap4*/), d_buf(0)
 {}
 
 Int64::Int64(const Int64 &copy_from) : BaseType(copy_from)
@@ -125,41 +125,38 @@ Int64::operator=(const Int64 &rhs)
 }
 
 unsigned int
-Int64::width(bool)
+Int64::width(bool) const
 {
     return sizeof(dods_int64);
 }
 
-bool
-Int64::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval)
+void
+Int64::compute_checksum(Crc32 &checksum)
 {
-    dds.timeout_on();
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
 
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+Int64::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
     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();
-
-    assert(typeid(m) == typeid(DAP4StreamMarshaller));
-
-    static_cast<DAP4StreamMarshaller*>(&m)->put_int64( d_buf ) ;
+        read();          // read() throws Error
 
-    return true;
+    m.put_int64( d_buf ) ;
 }
 
-bool
-Int64::deserialize(UnMarshaller &um, DDS *, bool)
+void
+Int64::deserialize(D4StreamUnMarshaller &um, DMR &)
 {
-    assert(typeid(um) == typeid(DAP4StreamUnMarshaller));
-
-    static_cast<DAP4StreamUnMarshaller*>(&um)->get_int64( d_buf ) ;
-
-    return false;
+    um.get_int64( d_buf ) ;
 }
 
 dods_int64
@@ -177,22 +174,14 @@ Int64::set_value(dods_int64 i)
     return true;
 }
 
-void
-Int64::print_val(FILE *out, string space, bool print_decl_p)
-{
-    ostringstream oss;
-    print_val(oss, space, print_decl_p);
-    fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
-}
-
 void Int64::print_val(ostream &out, string space, bool print_decl_p)
 {
     if (print_decl_p) {
         print_decl(out, space, false);
-        out << " = " << (dods_int64) d_buf << ";\n";
+        out << " = " << d_buf << ";\n";
     }
     else
-        out << (int) d_buf;
+        out << d_buf;
 }
 
 bool
diff --git a/Int64.h b/Int64.h
index d3178f6..411dd3c 100644
--- a/Int64.h
+++ b/Int64.h
@@ -48,8 +48,12 @@ class UnMarshaller;
 
 class Int64: public BaseType
 {
-    unsigned int val2buf(void *, bool)  { throw InternalErr(__FILE__, __LINE__, "Not implemented for Int64"); }
-    unsigned int buf2val(void **) { throw InternalErr(__FILE__, __LINE__, "Not implemented for Int64"); }
+	virtual unsigned int val2buf(void *val, bool)  {
+    	set_value(*reinterpret_cast<dods_int64*>(val));
+    	return sizeof(dods_int64);
+    }
+    virtual unsigned int buf2val(void **) { throw InternalErr(__FILE__, __LINE__, "Not implemented for Int64"); }
+    virtual void print_val(FILE *, string, bool) { throw InternalErr(__FILE__, __LINE__, "Not implemented for Int64"); }
 
 protected:
     dods_int64 d_buf;
@@ -66,18 +70,17 @@ public:
 
     virtual BaseType *ptr_duplicate();
 
-    virtual unsigned int width(bool constrained = false);
+    virtual unsigned int width(bool constrained = false) const;
 
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval = true);
-    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
 
     virtual bool set_value(dods_int64 i);
     virtual dods_int64 value() const;
 
-    virtual void print_val(FILE *out, string space = "",
-                           bool print_decl_p = true);
-    virtual void print_val(ostream &out, string space = "",
-                           bool print_decl_p = true);
+    virtual void print_val(ostream &out, string space = "", bool print_decl_p = true);
 
     virtual bool ops(BaseType *b, int op);
 
diff --git a/Int8.cc b/Int8.cc
index 685965c..395aa74 100644
--- a/Int8.cc
+++ b/Int8.cc
@@ -41,8 +41,8 @@
 #include "Str.h"
 #include "Url.h"
 
-#include "DAP4StreamMarshaller.h"
-#include "DAP4StreamUnMarshaller.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
 
 #include "DDS.h"
 #include "util.h"
@@ -61,7 +61,7 @@ namespace libdap {
 
     @param n A string containing the name of the variable to be created.
 */
-Int8::Int8(const string &n) : BaseType(n, dods_int8_c)
+Int8::Int8(const string &n) : BaseType(n, dods_int8_c), d_buf(0)
 {}
 
 /** The Int8 server-side constructor accepts the name of the variable and
@@ -71,7 +71,7 @@ Int8::Int8(const string &n) : BaseType(n, dods_int8_c)
     @param d A string containing the name of the dataset from which this
     variable is created
 */
-Int8::Int8(const string &n, const string &d) : BaseType(n, d, dods_int8_c)
+Int8::Int8(const string &n, const string &d) : BaseType(n, d, dods_int8_c), d_buf(0)
 {}
 
 Int8::Int8(const Int8 &copy_from) : BaseType(copy_from)
@@ -99,39 +99,38 @@ Int8::operator=(const Int8 &rhs)
 }
 
 unsigned int
-Int8::width(bool)
+Int8::width(bool) const
 {
     return sizeof(dods_int8);
 }
 
-bool
-Int8::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval)
+void
+Int8::compute_checksum(Crc32 &checksum)
 {
-    dds.timeout_on();
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
 
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+Int8::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
     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();
-
-    assert(typeid(m)==typeid(DAP4StreamMarshaller));
-    static_cast<DAP4StreamMarshaller&>(m).put_int8( d_buf ) ;
+        read();          // read() throws Error
 
-    return true;
+    m.put_int8( d_buf ) ;
 }
 
-bool
-Int8::deserialize(UnMarshaller &um, DDS *, bool)
+void
+Int8::deserialize(D4StreamUnMarshaller &um, DMR &)
 {
-    assert(typeid(um)==typeid(DAP4StreamUnMarshaller));
-    static_cast<DAP4StreamUnMarshaller&>(um).get_int8( d_buf ) ;
-
-    return false;
+    um.get_int8( d_buf ) ;
 }
 
 dods_int8
@@ -149,23 +148,14 @@ Int8::set_value(dods_int8 i)
     return true;
 }
 
-void
-Int8::print_val(FILE *out, string space, bool print_decl_p)
-{
-    ostringstream oss;
-    print_val(oss, space, print_decl_p);
-    fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
-}
-
-void
-Int8::print_val(ostream &out, string space, bool print_decl_p)
+void Int8::print_val(ostream &out, string space, bool print_decl_p)
 {
-    if (print_decl_p) {
-        print_decl(out, space, false);
-	out << " = " << d_buf << ";\n" ;
-    }
-    else
-	out << d_buf ;
+	if (print_decl_p) {
+		print_decl(out, space, false);
+		out << " = " << d_buf << ";\n";
+	}
+	else
+		out << (int)d_buf;
 }
 
 bool
diff --git a/Int8.h b/Int8.h
index d0182bb..bb9144e 100644
--- a/Int8.h
+++ b/Int8.h
@@ -37,12 +37,17 @@
 namespace libdap
 {
 
-/** @brief Holds a 16-bit signed integer value. */
+/** @brief Holds an 8-bit signed integer value. */
 
 class Int8: public BaseType
 {
-    virtual unsigned int val2buf(void *, bool)  { throw InternalErr(__FILE__, __LINE__, "Not implemented for Int8"); }
-    virtual unsigned int buf2val(void **)  { throw InternalErr(__FILE__, __LINE__, "Not implemented for Int8"); }
+	// This is used in BaseType *Vector::var(unsigned int i)
+	virtual unsigned int val2buf(void *val, bool)  {
+    	set_value(*reinterpret_cast<dods_int8*>(val));
+    	return sizeof(dods_int8);
+    }
+    virtual unsigned int buf2val(void **) { throw InternalErr(__FILE__, __LINE__, "buf2val: Not implemented for Int8"); }
+    virtual void print_val(FILE *, string , bool) { throw InternalErr(__FILE__, __LINE__, "print_val: Not implemented for Int8"); }
 
 protected:
     dods_int8 d_buf;
@@ -59,18 +64,17 @@ public:
 
     virtual BaseType *ptr_duplicate();
 
-    virtual unsigned int width(bool constrained = false);
+    virtual unsigned int width(bool constrained = false) const;
 
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval = true);
-    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
 
     virtual dods_int8 value() const;
     virtual bool set_value(dods_int8 val);
 
-    virtual void print_val(FILE *out, string space = "",
-                           bool print_decl_p = true);
-    virtual void print_val(ostream &out, string space = "",
-                           bool print_decl_p = true);
+    virtual void print_val(ostream &out, string space = "", bool print_decl_p = true);
 
     virtual bool ops(BaseType *b, int op);
 
diff --git a/InternalErr.cc b/InternalErr.cc
index 4a55a47..ca1e2a9 100644
--- a/InternalErr.cc
+++ b/InternalErr.cc
@@ -34,10 +34,6 @@
 
 #include "config.h"
 
-static char rcsid[] not_used =
-    {"$Id: InternalErr.cc 27197 2013-10-01 21:29:54Z jimg $"
-    };
-
 #include <string>
 #include <sstream>
 
diff --git a/Makefile.am b/Makefile.am
index 50aed3f..ffc4d48 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,41 +1,33 @@
-# Build libdap, libtest-types.a, getdap
+# Build libdap, libtest-types.a, getdap, getdap4
 
-AUTOMAKE_OPTIONS = foreign check-news
+AUTOMAKE_OPTIONS = foreign check-news subdir-objects
 ACLOCAL_AMFLAGS = -I conf -I gl/m4
 
 aclocaldir=$(datadir)/aclocal
 pkgconfigdir=$(libdir)/pkgconfig
 
-AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/GNU $(XML2_CFLAGS)
+AM_CPPFLAGS = -I$(top_builddir)/gl -I$(top_srcdir)/gl -I$(top_srcdir)/GNU $(XML2_CFLAGS)
 AM_CXXFLAGS = 
+CXXFLAGS = 
 
 if COMPILER_IS_GCC
 AM_CXXFLAGS += -Wall -W -Wcast-align
 endif
 
-# if USING_GRIDFIELDS
-# AM_CPPFLAGS += $(GF_CFLAGS)
-# GRIDFIELDS = ugridFunctions
-# endif
-
-AM_YFLAGS = -d -v -t
-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
+# ./configure --disable-shared CXXFLAGS=...
 # or ./configure --enable-developer --disable-shared
 # the --disable-shared is not required, but it seems to help with debuggers.
 CXXFLAGS_DEBUG = -g3 -O0  -Wall -W -Wcast-align 
-# -Werror There are some warnings in this code that are here to stay...
 TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
 
 if BUILD_DEVELOPER
 AM_CXXFLAGS += $(CXXFLAGS_DEBUG)
 endif
 
-SUBDIRS = gl . tests unit-tests
-DIST_SUBDIRS = gl tests unit-tests
+SUBDIRS = gl d4_ce .  tests unit-tests
+DIST_SUBDIRS = gl d4_ce tests unit-tests
 
 noinst_LTLIBRARIES = libparsers.la
 
@@ -43,17 +35,20 @@ lib_LTLIBRARIES = libdap.la libdapclient.la libdapserver.la
 
 bin_SCRIPTS = dap-config dap-config-pkgconfig
 
-bin_PROGRAMS = getdap
+bin_PROGRAMS = getdap getdap4
 
-BUILT_SOURCES = $(GRAM_SRC) dods-datatypes.h xdr-datatypes.h getdap.1 dap-config.1
+BUILT_SOURCES = $(GRAM_SRC) dods-datatypes.h xdr-datatypes.h getdap.1 dap-config.1 getdap4.1
 
-man_MANS = getdap.1 dap-config.1
+man_MANS = getdap.1 dap-config.1 getdap4.1
 
 %.1: %.man1
 	groff -t -e -mandoc -Tascii $< | col -bx > $@
 
 libparsers_la_SOURCES = $(GRAM_SRC) 
-libparsers_la_CPPFLAGS = $(AM_CPPFLAGS)
+libparsers_la_CPPFLAGS = $(XML2_CFLAGS)
+# Removed this because on CentOS 5 using gl/unistd.h with flex-generated
+# sources is broken - assume that flex is suitably portable on its own,
+# so the gl code is not needed anyway. jhrg 5/2/14 $(AM_CPPFLAGS)
 libparsers_la_LIBADD = $(XML2_LIBS)
 
 libdap_la_SOURCES = $(DAP_SRC) $(GNU_SRC)
@@ -63,7 +58,7 @@ endif
 
 libdap_la_LDFLAGS = -version-info $(LIBDAP_VERSION)
 libdap_la_CPPFLAGS = $(AM_CPPFLAGS)
-libdap_la_LIBADD = $(XML2_LIBS) $(PTHREAD_LIBS) gl/libgnu.la libparsers.la
+libdap_la_LIBADD = $(XML2_LIBS) $(PTHREAD_LIBS) gl/libgnu.la d4_ce/libd4_ce_parser.la libparsers.la
 if DAP4_DEFINED
     libdap_la_LIBADD += -lcrypto 
 endif
@@ -72,16 +67,17 @@ libdapclient_la_SOURCES = $(CLIENT_SRC)
 libdapclient_la_LDFLAGS = -version-info $(CLIENTLIB_VERSION)
 libdapclient_la_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS)
 libdapclient_la_LIBADD = $(CURL_LIBS) libdap.la $(PTHREAD_LIBS)
+if DAP4_DEFINED
+    libdapclient_la_SOURCES += $(DAP4_CLIENT_HDR) $(DAP4_CLIENT_SRC)
+endif
 
 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) 
-# TODO Until the compile-time issue with headers like BaseType.h depending on
-# configure params is fixed, always install these headers.
 if DAP4_DEFINED
-    pkginclude_HEADERS += $(DAP4_ONLY_HDR)
+    pkginclude_HEADERS += $(DAP4_ONLY_HDR) $(DAP4_CLIENT_HDR)
 endif
 
 noinst_HEADERS = config_dap.h
@@ -90,6 +86,10 @@ getdap_SOURCES = getdap.cc
 getdap_LDADD = libdapclient.la libdap.la
 getdap_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS)
 
+getdap4_SOURCES = getdap4.cc
+getdap4_LDADD = libdapclient.la libdap.la
+getdap4_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS)
+
 LEX_YACC_EXTRA = das.lex das.yy dds.lex dds.yy ce_expr.lex ce_expr.yy \
 Error.lex Error.yy
 
@@ -97,18 +97,13 @@ 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 getdap.man1 dap-config.man1
+	$(GRAM_SRC) OSX_Resources getdap.man1 dap-config.man1 getdap4.man1
 
 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 getdap.1 dap-config.1
-
-# Not nearly as clean as it could be, but this removes .svn directories
-# in subdirs.
-dist-hook:
-	rm -rf `find $(distdir) -name .svn`
+    xdr-datatypes.h getdap.1 dap-config.1 getdap4.1
 
 # Copy the generated grammar files to the 'grammarfiles' directory.
 .PHONY: grammarfiles
@@ -134,6 +129,7 @@ cccc:
 .PHONY: fortify
 fortify: $(BUILT_SOURCES)
 	(cd gl && sourceanalyzer -b @PACKAGE at -gl $(MAKE) $(MFLAGS) )
+	(cd d4_ce && sourceanalyzer -b @PACKAGE at -d4_ce $(MAKE) $(MFLAGS) )
 	sourceanalyzer -b @PACKAGE at -parsers $(MAKE) $(MFLAGS) libparsers.la
 	sourceanalyzer -b @PACKAGE@ $(MAKE) $(MFLAGS) libdap.la libdapserver.la libdapclient.la
 	sourceanalyzer -b @PACKAGE@ -scan -f @PACKAGE at -@PACKAGE_VERSION at .fpr
@@ -143,9 +139,10 @@ fortify: $(BUILT_SOURCES)
 # 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
+	( cd gl && $(MAKE) $(MFLAGS) )
+	( cd d4_ce && $(MAKE) $(MFLAGS) )
+	$(MAKE)  $(MFLAGS) libparsers.la
+	sourceanalyzer -b @PACKAGE@ $(MAKE) $(MFLAGS) libdap.la libdapserver.la libdapclient.la
 	sourceanalyzer -b @PACKAGE@ -scan -f @PACKAGE at -@PACKAGE_VERSION at .fpr
 
 # No longer used? jhrg 1/29/13
@@ -248,13 +245,13 @@ DAP_SRC = AttrTable.cc DAS.cc DDS.cc DataDDS.cc DDXParserSAX2.cc	\
 	Operators.h XDRUtils.cc XDRFileMarshaller.cc			\
 	XDRStreamMarshaller.cc XDRFileUnMarshaller.cc			\
 	XDRStreamUnMarshaller.cc mime_util.cc Keywords2.cc XMLWriter.cc \
-	ServerFunctionsList.cc ServerFunction.cc
+	ServerFunctionsList.cc ServerFunction.cc DapXmlNamespaces.cc
 
-# DAPCache3.cc 
-
-DAP4_ONLY_SRC = DAP4StreamMarshaller.cc DAP4StreamUnMarshaller.cc Int64.cc \
+DAP4_ONLY_SRC = D4StreamMarshaller.cc D4StreamUnMarshaller.cc Int64.cc \
         UInt64.cc Int8.cc D4ParserSax2.cc D4BaseTypeFactory.cc \
-        D4Maps.cc D4Dimensions.cc  D4EnumDef.cc D4Group.cc
+        D4Dimensions.cc  D4EnumDefs.cc D4Group.cc DMR.cc \
+        D4Attributes.cc D4Enum.cc chunked_ostream.cc chunked_istream.cc \
+        D4Sequence.cc D4Maps.cc D4Opaque.cc D4AsyncUtil.cc D4RValue.cc
 
 Operators.h: ce_expr.tab.hh
 
@@ -264,6 +261,8 @@ Operators.h: ce_expr.tab.hh
 CLIENT_SRC = RCReader.cc Connect.cc HTTPConnect.cc HTTPCache.cc	\
 	util_mit.cc ResponseTooBigErr.cc HTTPCacheTable.cc
 
+DAP4_CLIENT_SRC = D4Connect.cc
+
 SERVER_SRC = DODSFilter.cc Ancillary.cc
 # ResponseBuilder.cc ResponseCache.cc
 
@@ -273,26 +272,29 @@ DAP_HDR = AttrTable.h DAS.h DDS.h DataDDS.h DDXParserSAX2.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 		\
+	dods-datatypes.h Type.h		\
 	util_mit.h expr.h Clause.h RValue.h ConstraintEvaluator.h	\
 	ce_parser.h DapIndent.h DapObj.h XDRFileMarshaller.h		\
 	Marshaller.h UnMarshaller.h XDRFileUnMarshaller.h		\
 	XDRStreamMarshaller.h XDRUtils.h xdr-datatypes.h mime_util.h	\
 	cgi_util.h XDRStreamUnMarshaller.h Keywords2.h XMLWriter.h \
-	ServerFunctionsList.h ServerFunction.h
+	ServerFunctionsList.h ServerFunction.h media_types.h \
+	DapXmlNamespaces.h parser-util.h
 
-# DAPCache.h
-
-DAP4_ONLY_HDR = DAP4StreamMarshaller.h DAP4StreamUnMarshaller.h Int64.h \
-        UInt64.h Int8.h D4ParserSax2.h D4BaseTypeFactory.h D4ParseError.h \
-        D4Maps.h D4Dimensions.h D4EnumDef.h D4Group.h
+DAP4_ONLY_HDR = D4StreamMarshaller.h D4StreamUnMarshaller.h Int64.h \
+        UInt64.h Int8.h D4ParserSax2.h D4BaseTypeFactory.h \
+        D4Maps.h D4Dimensions.h D4EnumDefs.h D4Group.h DMR.h D4Attributes.h \
+        D4AttributeType.h D4Enum.h chunked_stream.h chunked_ostream.h \
+        chunked_istream.h D4Sequence.h crc.h D4Opaque.h D4AsyncUtil.h \
+        D4Function.h D4RValue.h
 
 if USE_C99_TYPES
 dods-datatypes.h: dods-datatypes-static.h
+	cp -p $< dods-datatypes.h
 else
 dods-datatypes.h: dods-datatypes-config.h
-endif
 	cp -p $< dods-datatypes.h
+endif
 
 xdr-datatypes.h: xdr-datatypes-config.h
 	cp -p $< xdr-datatypes.h
@@ -303,6 +305,8 @@ CLIENT_HDR = RCReader.h Connect.h HTTPConnect.h HTTPCache.h		\
 	StdinResponse.h SignalHandlerRegisteredErr.h			\
 	ResponseTooBigErr.h Resource.h HTTPCacheTable.h HTTPCacheMacros.h
 
+DAP4_CLIENT_HDR = D4Connect.h
+
 SERVER_HDR = DODSFilter.h AlarmHandler.h EventHandler.h Ancillary.h
 #	ResponseBuilder.h ResponseCache.h
 
diff --git a/Makefile.in b/Makefile.in
index 8d5edcb..25eace8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -15,7 +15,7 @@
 
 @SET_MAKE@
 
-# Build libdap, libtest-types.a, getdap
+# Build libdap, libtest-types.a, getdap, getdap4
 
 
 
@@ -58,45 +58,51 @@ build_triplet = @build@
 host_triplet = @host@
 @COMPILER_IS_GCC_TRUE at am__append_1 = -Wall -W -Wcast-align
 @BUILD_DEVELOPER_TRUE at am__append_2 = $(CXXFLAGS_DEBUG)
-bin_PROGRAMS = getdap$(EXEEXT)
+bin_PROGRAMS = getdap$(EXEEXT) getdap4$(EXEEXT)
 @DAP4_DEFINED_TRUE at am__append_3 = $(DAP4_ONLY_SRC)
 @DAP4_DEFINED_TRUE at am__append_4 = -lcrypto 
-# TODO Until the compile-time issue with headers like BaseType.h depending on
-# configure params is fixed, always install these headers.
- at DAP4_DEFINED_TRUE@am__append_5 = $(DAP4_ONLY_HDR)
+ at DAP4_DEFINED_TRUE@am__append_5 = $(DAP4_CLIENT_HDR) $(DAP4_CLIENT_SRC)
+ at DAP4_DEFINED_TRUE@am__append_6 = $(DAP4_ONLY_HDR) $(DAP4_CLIENT_HDR)
 subdir = .
 DIST_COMMON = README $(am__configure_deps) \
 	$(am__pkginclude_HEADERS_DIST) $(dist_aclocal_DATA) \
 	$(noinst_HEADERS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
-	$(srcdir)/config.h.in $(srcdir)/dap-config.in \
-	$(srcdir)/dods-datatypes-config.h.in $(srcdir)/doxy.conf.in \
-	$(srcdir)/libdap.pc.in $(srcdir)/libdapclient.pc.in \
-	$(srcdir)/libdapserver.pc.in $(srcdir)/main_page.doxygen.in \
-	$(srcdir)/xdr-datatypes-config.h.in \
-	$(top_srcdir)/conf/config.guess $(top_srcdir)/conf/config.sub \
+	$(srcdir)/abi_checker.xml.in $(srcdir)/config.h.in \
+	$(srcdir)/dap-config.in $(srcdir)/dods-datatypes-config.h.in \
+	$(srcdir)/doxy.conf.in $(srcdir)/libdap.pc.in \
+	$(srcdir)/libdapclient.pc.in $(srcdir)/libdapserver.pc.in \
+	$(srcdir)/main_page.doxygen.in \
+	$(srcdir)/xdr-datatypes-config.h.in $(top_srcdir)/conf/compile \
+	$(top_srcdir)/conf/config.guess \
+	$(top_srcdir)/conf/config.rpath $(top_srcdir)/conf/config.sub \
 	$(top_srcdir)/conf/depcomp $(top_srcdir)/conf/install-sh \
 	$(top_srcdir)/conf/ltmain.sh $(top_srcdir)/conf/missing \
 	$(top_srcdir)/configure COPYING ChangeLog INSTALL NEWS \
-	conf/config.guess conf/config.sub conf/depcomp conf/install-sh \
-	conf/ltmain.sh conf/missing
+	conf/compile conf/config.guess conf/config.rpath \
+	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/byteswap.m4 $(top_srcdir)/gl/m4/codeset.m4 \
 	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/eealloc.m4 \
 	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/extern-inline.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/lib-ld.m4 $(top_srcdir)/gl/m4/lib-link.m4 \
+	$(top_srcdir)/gl/m4/lib-prefix.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/locale_h.m4 \
-	$(top_srcdir)/gl/m4/localeconv.m4 \
+	$(top_srcdir)/gl/m4/localeconv.m4 $(top_srcdir)/gl/m4/lock.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/mbtowc.m4 \
@@ -105,17 +111,18 @@ am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
 	$(top_srcdir)/gl/m4/off_t.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/strcase.m4 \
-	$(top_srcdir)/gl/m4/strings_h.m4 \
+	$(top_srcdir)/gl/m4/stdlib_h.m4 \
 	$(top_srcdir)/gl/m4/sys_types_h.m4 \
+	$(top_srcdir)/gl/m4/threadlib.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/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/cppunit.m4 \
+	$(top_srcdir)/conf/gcov_valgrind.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) \
@@ -126,7 +133,7 @@ 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 \
-	main_page.doxygen doxy.conf dap-config
+	main_page.doxygen doxy.conf abi_checker.xml dap-config
 CONFIG_CLEAN_VPATH_FILES =
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
@@ -162,7 +169,8 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
 LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libdap_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
-	gl/libgnu.la libparsers.la $(am__DEPENDENCIES_1)
+	gl/libgnu.la d4_ce/libd4_ce_parser.la libparsers.la \
+	$(am__DEPENDENCIES_1)
 am__libdap_la_SOURCES_DIST = 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 \
@@ -173,10 +181,13 @@ am__libdap_la_SOURCES_DIST = AttrTable.cc DAS.cc DDS.cc DataDDS.cc \
 	XDRUtils.cc XDRFileMarshaller.cc XDRStreamMarshaller.cc \
 	XDRFileUnMarshaller.cc XDRStreamUnMarshaller.cc mime_util.cc \
 	Keywords2.cc XMLWriter.cc ServerFunctionsList.cc \
-	ServerFunction.cc GNU/GetOpt.cc GNU/GNURegex.cc \
-	DAP4StreamMarshaller.cc DAP4StreamUnMarshaller.cc Int64.cc \
-	UInt64.cc Int8.cc D4ParserSax2.cc D4BaseTypeFactory.cc \
-	D4Maps.cc D4Dimensions.cc D4EnumDef.cc D4Group.cc
+	ServerFunction.cc DapXmlNamespaces.cc GNU/GetOpt.cc \
+	GNU/GNURegex.cc D4StreamMarshaller.cc D4StreamUnMarshaller.cc \
+	Int64.cc UInt64.cc Int8.cc D4ParserSax2.cc \
+	D4BaseTypeFactory.cc D4Dimensions.cc D4EnumDefs.cc D4Group.cc \
+	DMR.cc D4Attributes.cc D4Enum.cc chunked_ostream.cc \
+	chunked_istream.cc D4Sequence.cc D4Maps.cc D4Opaque.cc \
+	D4AsyncUtil.cc D4RValue.cc
 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 \
@@ -196,14 +207,21 @@ am__objects_1 = libdap_la-AttrTable.lo libdap_la-DAS.lo \
 	libdap_la-XDRFileUnMarshaller.lo \
 	libdap_la-XDRStreamUnMarshaller.lo libdap_la-mime_util.lo \
 	libdap_la-Keywords2.lo libdap_la-XMLWriter.lo \
-	libdap_la-ServerFunctionsList.lo libdap_la-ServerFunction.lo
-am__objects_2 = libdap_la-GetOpt.lo libdap_la-GNURegex.lo
-am__objects_3 = libdap_la-DAP4StreamMarshaller.lo \
-	libdap_la-DAP4StreamUnMarshaller.lo libdap_la-Int64.lo \
+	libdap_la-ServerFunctionsList.lo libdap_la-ServerFunction.lo \
+	libdap_la-DapXmlNamespaces.lo
+am__dirstamp = $(am__leading_dot)dirstamp
+am__objects_2 = GNU/libdap_la-GetOpt.lo GNU/libdap_la-GNURegex.lo
+am__objects_3 = libdap_la-D4StreamMarshaller.lo \
+	libdap_la-D4StreamUnMarshaller.lo libdap_la-Int64.lo \
 	libdap_la-UInt64.lo libdap_la-Int8.lo \
 	libdap_la-D4ParserSax2.lo libdap_la-D4BaseTypeFactory.lo \
-	libdap_la-D4Maps.lo libdap_la-D4Dimensions.lo \
-	libdap_la-D4EnumDef.lo libdap_la-D4Group.lo
+	libdap_la-D4Dimensions.lo libdap_la-D4EnumDefs.lo \
+	libdap_la-D4Group.lo libdap_la-DMR.lo \
+	libdap_la-D4Attributes.lo libdap_la-D4Enum.lo \
+	libdap_la-chunked_ostream.lo libdap_la-chunked_istream.lo \
+	libdap_la-D4Sequence.lo libdap_la-D4Maps.lo \
+	libdap_la-D4Opaque.lo libdap_la-D4AsyncUtil.lo \
+	libdap_la-D4RValue.lo
 @DAP4_DEFINED_TRUE at am__objects_4 = $(am__objects_3)
 am_libdap_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
 	$(am__objects_4)
@@ -213,34 +231,43 @@ libdap_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(CXXFLAGS) $(libdap_la_LDFLAGS) $(LDFLAGS) -o $@
 libdapclient_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libdap.la \
 	$(am__DEPENDENCIES_1)
+am__libdapclient_la_SOURCES_DIST = RCReader.cc Connect.cc \
+	HTTPConnect.cc HTTPCache.cc util_mit.cc ResponseTooBigErr.cc \
+	HTTPCacheTable.cc D4Connect.h D4Connect.cc
 am__objects_5 = 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_5)
+am__objects_6 =
+am__objects_7 = libdapclient_la-D4Connect.lo
+ at DAP4_DEFINED_TRUE@am__objects_8 = $(am__objects_6) $(am__objects_7)
+am_libdapclient_la_OBJECTS = $(am__objects_5) $(am__objects_8)
 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_6 = DODSFilter.lo Ancillary.lo
-am_libdapserver_la_OBJECTS = $(am__objects_6)
+am__objects_9 = DODSFilter.lo Ancillary.lo
+am_libdapserver_la_OBJECTS = $(am__objects_9)
 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_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am__objects_7 = libparsers_la-lex.das.lo libparsers_la-das.tab.lo \
+am__objects_10 = libparsers_la-lex.das.lo libparsers_la-das.tab.lo \
 	libparsers_la-lex.dds.lo libparsers_la-dds.tab.lo \
 	libparsers_la-lex.ce_expr.lo libparsers_la-ce_expr.tab.lo \
 	libparsers_la-lex.Error.lo libparsers_la-Error.tab.lo
-am_libparsers_la_OBJECTS = $(am__objects_7)
+am_libparsers_la_OBJECTS = $(am__objects_10)
 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
+am_getdap4_OBJECTS = getdap4-getdap4.$(OBJEXT)
+getdap4_OBJECTS = $(am_getdap4_OBJECTS)
+getdap4_DEPENDENCIES = libdapclient.la libdap.la
 SCRIPTS = $(bin_SCRIPTS)
 DEFAULT_INCLUDES = -I. at am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/conf/depcomp
@@ -266,10 +293,10 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	$(LDFLAGS) -o $@
 SOURCES = $(libdap_la_SOURCES) $(libdapclient_la_SOURCES) \
 	$(libdapserver_la_SOURCES) $(libparsers_la_SOURCES) \
-	$(getdap_SOURCES)
+	$(getdap_SOURCES) $(getdap4_SOURCES)
 DIST_SOURCES = $(am__libdap_la_SOURCES_DIST) \
-	$(libdapclient_la_SOURCES) $(libdapserver_la_SOURCES) \
-	$(libparsers_la_SOURCES) $(getdap_SOURCES)
+	$(am__libdapclient_la_SOURCES_DIST) $(libdapserver_la_SOURCES) \
+	$(libparsers_la_SOURCES) $(getdap_SOURCES) $(getdap4_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
 	html-recursive info-recursive install-data-recursive \
 	install-dvi-recursive install-exec-recursive \
@@ -292,22 +319,26 @@ am__pkginclude_HEADERS_DIST = AttrTable.h DAS.h DDS.h DataDDS.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 util_mit.h \
-	expr.h Clause.h RValue.h ConstraintEvaluator.h ce_parser.h \
-	DapIndent.h DapObj.h XDRFileMarshaller.h Marshaller.h \
-	UnMarshaller.h XDRFileUnMarshaller.h XDRStreamMarshaller.h \
-	XDRUtils.h xdr-datatypes.h mime_util.h cgi_util.h \
-	XDRStreamUnMarshaller.h Keywords2.h XMLWriter.h \
-	ServerFunctionsList.h ServerFunction.h GNU/GetOpt.h \
-	GNU/GNURegex.h RCReader.h Connect.h HTTPConnect.h HTTPCache.h \
+	parser.h debug.h dods-limits.h dods-datatypes.h Type.h \
+	util_mit.h expr.h Clause.h RValue.h ConstraintEvaluator.h \
+	ce_parser.h DapIndent.h DapObj.h XDRFileMarshaller.h \
+	Marshaller.h UnMarshaller.h XDRFileUnMarshaller.h \
+	XDRStreamMarshaller.h XDRUtils.h xdr-datatypes.h mime_util.h \
+	cgi_util.h XDRStreamUnMarshaller.h Keywords2.h XMLWriter.h \
+	ServerFunctionsList.h ServerFunction.h media_types.h \
+	DapXmlNamespaces.h parser-util.h GNU/GetOpt.h GNU/GNURegex.h \
+	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 \
 	HTTPCacheMacros.h DODSFilter.h AlarmHandler.h EventHandler.h \
-	Ancillary.h DAP4StreamMarshaller.h DAP4StreamUnMarshaller.h \
+	Ancillary.h D4StreamMarshaller.h D4StreamUnMarshaller.h \
 	Int64.h UInt64.h Int8.h D4ParserSax2.h D4BaseTypeFactory.h \
-	D4ParseError.h D4Maps.h D4Dimensions.h D4EnumDef.h D4Group.h
+	D4Maps.h D4Dimensions.h D4EnumDefs.h D4Group.h DMR.h \
+	D4Attributes.h D4AttributeType.h D4Enum.h chunked_stream.h \
+	chunked_ostream.h chunked_istream.h D4Sequence.h crc.h \
+	D4Opaque.h D4AsyncUtil.h D4Function.h D4RValue.h D4Connect.h
 HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
   distclean-recursive maintainer-clean-recursive
@@ -395,7 +426,7 @@ CURL_STATIC_LIBS = @CURL_STATIC_LIBS@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
+CXXFLAGS = 
 CYGPATH_W = @CYGPATH_W@
 DAPLIB_AGE = @DAPLIB_AGE@
 DAPLIB_CURRENT = @DAPLIB_CURRENT@
@@ -411,7 +442,6 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
-EVAL = @EVAL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GLIBC21 = @GLIBC21@
@@ -432,7 +462,6 @@ GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
 GNULIB_FCHDIR = @GNULIB_FCHDIR@
 GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
 GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
-GNULIB_FFS = @GNULIB_FFS@
 GNULIB_FSYNC = @GNULIB_FSYNC@
 GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
 GNULIB_GETCWD = @GNULIB_GETCWD@
@@ -486,6 +515,7 @@ GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
 GNULIB_REALPATH = @GNULIB_REALPATH@
 GNULIB_RMDIR = @GNULIB_RMDIR@
 GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
 GNULIB_SETENV = @GNULIB_SETENV@
 GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
 GNULIB_SETLOCALE = @GNULIB_SETLOCALE@
@@ -558,7 +588,6 @@ HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
 HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
 HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
 HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
-HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
 HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
 HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
 HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
@@ -572,7 +601,6 @@ HAVE_FCHDIR = @HAVE_FCHDIR@
 HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
 HAVE_FDATASYNC = @HAVE_FDATASYNC@
 HAVE_FEATURES_H = @HAVE_FEATURES_H@
-HAVE_FFS = @HAVE_FFS@
 HAVE_FSYNC = @HAVE_FSYNC@
 HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
 HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
@@ -621,6 +649,7 @@ HAVE_READLINK = @HAVE_READLINK@
 HAVE_READLINKAT = @HAVE_READLINKAT@
 HAVE_REALPATH = @HAVE_REALPATH@
 HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
 HAVE_SETENV = @HAVE_SETENV@
 HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
 HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
@@ -628,8 +657,6 @@ 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_STRCASECMP = @HAVE_STRCASECMP@
-HAVE_STRINGS_H = @HAVE_STRINGS_H@
 HAVE_STRTOD = @HAVE_STRTOD@
 HAVE_STRTOLL = @HAVE_STRTOLL@
 HAVE_STRTOULL = @HAVE_STRTOULL@
@@ -646,6 +673,7 @@ HAVE_UNLINKAT = @HAVE_UNLINKAT@
 HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
 HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
 HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_VALGRIND = @HAVE_VALGRIND@
 HAVE_WCHAR_H = @HAVE_WCHAR_H@
 HAVE_WCHAR_T = @HAVE_WCHAR_T@
 HAVE_WCPCPY = @HAVE_WCPCPY@
@@ -700,8 +728,12 @@ LEXLIB = @LEXLIB@
 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
 LIBDAP_VERSION = @LIBDAP_VERSION@
 LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
 LIBS = @LIBS@
+LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -711,7 +743,10 @@ LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
 LOCALE_JA = @LOCALE_JA@
 LOCALE_ZH_CN = @LOCALE_ZH_CN@
 LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -720,7 +755,6 @@ NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_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_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
 NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_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@
@@ -730,7 +764,6 @@ NEXT_LOCALE_H = @NEXT_LOCALE_H@
 NEXT_STDDEF_H = @NEXT_STDDEF_H@
 NEXT_STDINT_H = @NEXT_STDINT_H@
 NEXT_STDLIB_H = @NEXT_STDLIB_H@
-NEXT_STRINGS_H = @NEXT_STRINGS_H@
 NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
 NEXT_UNISTD_H = @NEXT_UNISTD_H@
 NEXT_WCHAR_H = @NEXT_WCHAR_H@
@@ -770,6 +803,7 @@ REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
 REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
 REPLACE_GETCWD = @REPLACE_GETCWD@
 REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
 REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
 REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
 REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
@@ -793,6 +827,7 @@ REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
 REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
 REPLACE_NULL = @REPLACE_NULL@
 REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
 REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
 REPLACE_PUTENV = @REPLACE_PUTENV@
 REPLACE_PWRITE = @REPLACE_PWRITE@
@@ -898,6 +933,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -908,44 +944,39 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 xmlprivatelibs = @xmlprivatelibs@
 xmlprivatereq = @xmlprivatereq@
-AUTOMAKE_OPTIONS = foreign check-news
+AUTOMAKE_OPTIONS = foreign check-news subdir-objects
 ACLOCAL_AMFLAGS = -I conf -I gl/m4
 aclocaldir = $(datadir)/aclocal
 pkgconfigdir = $(libdir)/pkgconfig
-AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/GNU $(XML2_CFLAGS)
+AM_CPPFLAGS = -I$(top_builddir)/gl -I$(top_srcdir)/gl -I$(top_srcdir)/GNU $(XML2_CFLAGS)
 AM_CXXFLAGS = $(am__append_1) $(am__append_2)
 
-# if USING_GRIDFIELDS
-# AM_CPPFLAGS += $(GF_CFLAGS)
-# GRIDFIELDS = ugridFunctions
-# endif
-AM_YFLAGS = -d -v -t
-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
+# ./configure --disable-shared CXXFLAGS=...
 # or ./configure --enable-developer --disable-shared
 # the --disable-shared is not required, but it seems to help with debuggers.
 CXXFLAGS_DEBUG = -g3 -O0  -Wall -W -Wcast-align 
-# -Werror There are some warnings in this code that are here to stay...
 TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
-SUBDIRS = gl . tests unit-tests
-DIST_SUBDIRS = gl tests unit-tests
+SUBDIRS = gl d4_ce .  tests unit-tests
+DIST_SUBDIRS = gl d4_ce tests unit-tests
 noinst_LTLIBRARIES = libparsers.la
 lib_LTLIBRARIES = libdap.la libdapclient.la libdapserver.la
 bin_SCRIPTS = dap-config dap-config-pkgconfig
-BUILT_SOURCES = $(GRAM_SRC) dods-datatypes.h xdr-datatypes.h getdap.1 dap-config.1
-man_MANS = getdap.1 dap-config.1
+BUILT_SOURCES = $(GRAM_SRC) dods-datatypes.h xdr-datatypes.h getdap.1 dap-config.1 getdap4.1
+man_MANS = getdap.1 dap-config.1 getdap4.1
 libparsers_la_SOURCES = $(GRAM_SRC) 
-libparsers_la_CPPFLAGS = $(AM_CPPFLAGS)
+libparsers_la_CPPFLAGS = $(XML2_CFLAGS)
+# Removed this because on CentOS 5 using gl/unistd.h with flex-generated
+# sources is broken - assume that flex is suitably portable on its own,
+# so the gl code is not needed anyway. jhrg 5/2/14 $(AM_CPPFLAGS)
 libparsers_la_LIBADD = $(XML2_LIBS)
 libdap_la_SOURCES = $(DAP_SRC) $(GNU_SRC) $(am__append_3)
 libdap_la_LDFLAGS = -version-info $(LIBDAP_VERSION)
 libdap_la_CPPFLAGS = $(AM_CPPFLAGS)
 libdap_la_LIBADD = $(XML2_LIBS) $(PTHREAD_LIBS) gl/libgnu.la \
-	libparsers.la $(am__append_4)
-libdapclient_la_SOURCES = $(CLIENT_SRC) 
+	d4_ce/libd4_ce_parser.la libparsers.la $(am__append_4)
+libdapclient_la_SOURCES = $(CLIENT_SRC) $(am__append_5)
 libdapclient_la_LDFLAGS = -version-info $(CLIENTLIB_VERSION)
 libdapclient_la_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS)
 libdapclient_la_LIBADD = $(CURL_LIBS) libdap.la $(PTHREAD_LIBS)
@@ -953,11 +984,14 @@ 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) \
-	$(am__append_5)
+	$(am__append_6)
 noinst_HEADERS = config_dap.h
 getdap_SOURCES = getdap.cc
 getdap_LDADD = libdapclient.la libdap.la
 getdap_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS)
+getdap4_SOURCES = getdap4.cc
+getdap4_LDADD = libdapclient.la libdap.la
+getdap4_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS)
 LEX_YACC_EXTRA = das.lex das.yy dds.lex dds.yy ce_expr.lex ce_expr.yy \
 Error.lex Error.yy
 
@@ -965,12 +999,12 @@ 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 getdap.man1 dap-config.man1
+	$(GRAM_SRC) OSX_Resources getdap.man1 dap-config.man1 getdap4.man1
 
 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 getdap.1 dap-config.1
+    xdr-datatypes.h getdap.1 dap-config.1 getdap4.1
 
 
 ###########################################################################
@@ -1001,13 +1035,13 @@ DAP_SRC = AttrTable.cc DAS.cc DDS.cc DataDDS.cc DDXParserSAX2.cc	\
 	Operators.h XDRUtils.cc XDRFileMarshaller.cc			\
 	XDRStreamMarshaller.cc XDRFileUnMarshaller.cc			\
 	XDRStreamUnMarshaller.cc mime_util.cc Keywords2.cc XMLWriter.cc \
-	ServerFunctionsList.cc ServerFunction.cc
+	ServerFunctionsList.cc ServerFunction.cc DapXmlNamespaces.cc
 
-
-# DAPCache3.cc 
-DAP4_ONLY_SRC = DAP4StreamMarshaller.cc DAP4StreamUnMarshaller.cc Int64.cc \
+DAP4_ONLY_SRC = D4StreamMarshaller.cc D4StreamUnMarshaller.cc Int64.cc \
         UInt64.cc Int8.cc D4ParserSax2.cc D4BaseTypeFactory.cc \
-        D4Maps.cc D4Dimensions.cc  D4EnumDef.cc D4Group.cc
+        D4Dimensions.cc  D4EnumDefs.cc D4Group.cc DMR.cc \
+        D4Attributes.cc D4Enum.cc chunked_ostream.cc chunked_istream.cc \
+        D4Sequence.cc D4Maps.cc D4Opaque.cc D4AsyncUtil.cc D4RValue.cc
 
 
 # Operators.h is included in with the source to prevent it from bing installed
@@ -1015,6 +1049,7 @@ DAP4_ONLY_SRC = DAP4StreamMarshaller.cc DAP4StreamUnMarshaller.cc Int64.cc \
 CLIENT_SRC = RCReader.cc Connect.cc HTTPConnect.cc HTTPCache.cc	\
 	util_mit.cc ResponseTooBigErr.cc HTTPCacheTable.cc
 
+DAP4_CLIENT_SRC = D4Connect.cc
 SERVER_SRC = DODSFilter.cc Ancillary.cc
 # ResponseBuilder.cc ResponseCache.cc
 DAP_HDR = AttrTable.h DAS.h DDS.h DataDDS.h DDXParserSAX2.h		\
@@ -1023,19 +1058,21 @@ DAP_HDR = AttrTable.h DAS.h DDS.h DataDDS.h DDXParserSAX2.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 		\
+	dods-datatypes.h Type.h		\
 	util_mit.h expr.h Clause.h RValue.h ConstraintEvaluator.h	\
 	ce_parser.h DapIndent.h DapObj.h XDRFileMarshaller.h		\
 	Marshaller.h UnMarshaller.h XDRFileUnMarshaller.h		\
 	XDRStreamMarshaller.h XDRUtils.h xdr-datatypes.h mime_util.h	\
 	cgi_util.h XDRStreamUnMarshaller.h Keywords2.h XMLWriter.h \
-	ServerFunctionsList.h ServerFunction.h
-
+	ServerFunctionsList.h ServerFunction.h media_types.h \
+	DapXmlNamespaces.h parser-util.h
 
-# DAPCache.h
-DAP4_ONLY_HDR = DAP4StreamMarshaller.h DAP4StreamUnMarshaller.h Int64.h \
-        UInt64.h Int8.h D4ParserSax2.h D4BaseTypeFactory.h D4ParseError.h \
-        D4Maps.h D4Dimensions.h D4EnumDef.h D4Group.h
+DAP4_ONLY_HDR = D4StreamMarshaller.h D4StreamUnMarshaller.h Int64.h \
+        UInt64.h Int8.h D4ParserSax2.h D4BaseTypeFactory.h \
+        D4Maps.h D4Dimensions.h D4EnumDefs.h D4Group.h DMR.h D4Attributes.h \
+        D4AttributeType.h D4Enum.h chunked_stream.h chunked_ostream.h \
+        chunked_istream.h D4Sequence.h crc.h D4Opaque.h D4AsyncUtil.h \
+        D4Function.h D4RValue.h
 
 CLIENT_HDR = RCReader.h Connect.h HTTPConnect.h HTTPCache.h		\
 	HTTPCacheDisconnectedMode.h HTTPCacheInterruptHandler.h		\
@@ -1043,6 +1080,7 @@ CLIENT_HDR = RCReader.h Connect.h HTTPConnect.h HTTPCache.h		\
 	StdinResponse.h SignalHandlerRegisteredErr.h			\
 	ResponseTooBigErr.h Resource.h HTTPCacheTable.h HTTPCacheMacros.h
 
+DAP4_CLIENT_HDR = D4Connect.h
 SERVER_HDR = DODSFilter.h AlarmHandler.h EventHandler.h Ancillary.h
 all: $(BUILT_SOURCES) config.h dods-datatypes-config.h xdr-datatypes-config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -1124,6 +1162,8 @@ main_page.doxygen: $(top_builddir)/config.status $(srcdir)/main_page.doxygen.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 doxy.conf: $(top_builddir)/config.status $(srcdir)/doxy.conf.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
+abi_checker.xml: $(top_builddir)/config.status $(srcdir)/abi_checker.xml.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)
@@ -1171,6 +1211,16 @@ clean-noinstLTLIBRARIES:
 	  echo rm -f $${locs}; \
 	  rm -f $${locs}; \
 	}
+GNU/$(am__dirstamp):
+	@$(MKDIR_P) GNU
+	@: > GNU/$(am__dirstamp)
+GNU/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) GNU/$(DEPDIR)
+	@: > GNU/$(DEPDIR)/$(am__dirstamp)
+GNU/libdap_la-GetOpt.lo: GNU/$(am__dirstamp) \
+	GNU/$(DEPDIR)/$(am__dirstamp)
+GNU/libdap_la-GNURegex.lo: GNU/$(am__dirstamp) \
+	GNU/$(DEPDIR)/$(am__dirstamp)
 libdap.la: $(libdap_la_OBJECTS) $(libdap_la_DEPENDENCIES) $(EXTRA_libdap_la_DEPENDENCIES) 
 	$(libdap_la_LINK) -rpath $(libdir) $(libdap_la_OBJECTS) $(libdap_la_LIBADD) $(LIBS)
 libdapclient.la: $(libdapclient_la_OBJECTS) $(libdapclient_la_DEPENDENCIES) $(EXTRA_libdapclient_la_DEPENDENCIES) 
@@ -1228,6 +1278,9 @@ clean-binPROGRAMS:
 getdap$(EXEEXT): $(getdap_OBJECTS) $(getdap_DEPENDENCIES) $(EXTRA_getdap_DEPENDENCIES) 
 	@rm -f getdap$(EXEEXT)
 	$(CXXLINK) $(getdap_OBJECTS) $(getdap_LDADD) $(LIBS)
+getdap4$(EXEEXT): $(getdap4_OBJECTS) $(getdap4_DEPENDENCIES) $(EXTRA_getdap4_DEPENDENCIES) 
+	@rm -f getdap4$(EXEEXT)
+	$(CXXLINK) $(getdap4_OBJECTS) $(getdap4_LDADD) $(LIBS)
 install-binSCRIPTS: $(bin_SCRIPTS)
 	@$(NORMAL_INSTALL)
 	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
@@ -1266,6 +1319,10 @@ uninstall-binSCRIPTS:
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
+	-rm -f GNU/libdap_la-GNURegex.$(OBJEXT)
+	-rm -f GNU/libdap_la-GNURegex.lo
+	-rm -f GNU/libdap_la-GetOpt.$(OBJEXT)
+	-rm -f GNU/libdap_la-GetOpt.lo
 
 distclean-compile:
 	-rm -f *.tab.c
@@ -1273,6 +1330,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Ancillary.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DODSFilter.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/getdap-getdap.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/getdap4-getdap4.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Array.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-AttrTable.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-BaseType.Plo at am__quote@
@@ -1281,24 +1339,30 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Clause.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-ConstraintEvaluator.Plo at am__quote@
 @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-D4AsyncUtil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4Attributes.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4BaseTypeFactory.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4Dimensions.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4EnumDef.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4Enum.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4EnumDefs.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4Group.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4Maps.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4Opaque.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4ParserSax2.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DAP4StreamMarshaller.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DAP4StreamUnMarshaller.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4RValue.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4Sequence.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4StreamMarshaller.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-D4StreamUnMarshaller.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DAS.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DDS.Plo at am__quote@
 @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-DMR.Plo at am__quote@
 @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-DapXmlNamespaces.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DataDDS.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Error.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Float32.Plo at am__quote@
 @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-GetOpt.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Grid.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Int16.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Int32.Plo at am__quote@
@@ -1324,12 +1388,15 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-XDRStreamUnMarshaller.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-XDRUtils.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-XMLWriter.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-chunked_istream.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-chunked_ostream.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-escaping.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-mime_util.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-parser-util.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-util.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-xdrutil_ppc.Plo at am__quote@
 @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-D4Connect.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-HTTPCache.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-HTTPCacheTable.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-HTTPConnect.Plo at am__quote@
@@ -1344,24 +1411,29 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libparsers_la-lex.ce_expr.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libparsers_la-lex.das.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libparsers_la-lex.dds.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at GNU/$(DEPDIR)/libdap_la-GNURegex.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at GNU/$(DEPDIR)/libdap_la-GetOpt.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 am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+ at am__fastdepCC_FALSE@	$(COMPILE) -c -o $@ $<
 
 .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 am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_FALSE@	$(COMPILE) -c -o $@ `$(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 am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
@@ -1374,22 +1446,25 @@ libdap_la-xdrutil_ppc.lo: xdrutil_ppc.c
 @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 am__fastdepCXX_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @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 am__fastdepCXX_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @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 am__fastdepCXX_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
@@ -1688,33 +1763,40 @@ libdap_la-ServerFunction.lo: ServerFunction.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @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-ServerFunction.lo `test -f 'ServerFunction.cc' || echo '$(srcdir)/'`ServerFunction.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@
+libdap_la-DapXmlNamespaces.lo: DapXmlNamespaces.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-DapXmlNamespaces.lo -MD -MP -MF $(DEPDIR)/libdap_la-DapXmlNamespaces.Tpo -c -o libdap_la-DapXmlNamespaces.lo `test -f 'DapXmlNamespaces.cc' || echo '$(srcdir)/'`DapXmlNamespaces.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-DapXmlNamespaces.Tpo $(DEPDIR)/libdap_la-DapXmlNamespaces.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DapXmlNamespaces.cc' object='libdap_la-DapXmlNamespaces.lo' libtool=yes @AMDEPBACKSLASH@
 @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
+ 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-DapXmlNamespaces.lo `test -f 'DapXmlNamespaces.cc' || echo '$(srcdir)/'`DapXmlNamespaces.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@
+GNU/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 GNU/libdap_la-GetOpt.lo -MD -MP -MF GNU/$(DEPDIR)/libdap_la-GetOpt.Tpo -c -o GNU/libdap_la-GetOpt.lo `test -f 'GNU/GetOpt.cc' || echo '$(srcdir)/'`GNU/GetOpt.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) GNU/$(DEPDIR)/libdap_la-GetOpt.Tpo GNU/$(DEPDIR)/libdap_la-GetOpt.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='GNU/GetOpt.cc' object='GNU/libdap_la-GetOpt.lo' libtool=yes @AMDEPBACKSLASH@
 @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
+ 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 GNU/libdap_la-GetOpt.lo `test -f 'GNU/GetOpt.cc' || echo '$(srcdir)/'`GNU/GetOpt.cc
 
-libdap_la-DAP4StreamMarshaller.lo: DAP4StreamMarshaller.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-DAP4StreamMarshaller.lo -MD -MP -MF $(DEPDIR)/libdap_la-DAP4StreamMarshaller.Tpo -c -o libdap_la-DAP4StreamMarshaller.lo `test -f 'DAP4StreamMarshaller.cc' || echo '$(srcdir)/'`DAP4StreamMarshaller.cc
- at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-DAP4StreamMarshaller.Tpo $(DEPDIR)/libdap_la-DAP4StreamMarshaller.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DAP4StreamMarshaller.cc' object='libdap_la-DAP4StreamMarshaller.lo' libtool=yes @AMDEPBACKSLASH@
+GNU/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 GNU/libdap_la-GNURegex.lo -MD -MP -MF GNU/$(DEPDIR)/libdap_la-GNURegex.Tpo -c -o GNU/libdap_la-GNURegex.lo `test -f 'GNU/GNURegex.cc' || echo '$(srcdir)/'`GNU/GNURegex.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) GNU/$(DEPDIR)/libdap_la-GNURegex.Tpo GNU/$(DEPDIR)/libdap_la-GNURegex.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='GNU/GNURegex.cc' object='GNU/libdap_la-GNURegex.lo' libtool=yes @AMDEPBACKSLASH@
 @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-DAP4StreamMarshaller.lo `test -f 'DAP4StreamMarshaller.cc' || echo '$(srcdir)/'`DAP4StreamMarshaller.cc
+ 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 GNU/libdap_la-GNURegex.lo `test -f 'GNU/GNURegex.cc' || echo '$(srcdir)/'`GNU/GNURegex.cc
 
-libdap_la-DAP4StreamUnMarshaller.lo: DAP4StreamUnMarshaller.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-DAP4StreamUnMarshaller.lo -MD -MP -MF $(DEPDIR)/libdap_la-DAP4StreamUnMarshaller.Tpo -c -o libdap_la-DAP4StreamUnMarshaller.lo `test -f 'DAP4StreamUnMarshaller.cc' || echo '$(srcdir)/'`DAP4StreamUnMarshaller.cc
- at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-DAP4StreamUnMarshaller.Tpo $(DEPDIR)/libdap_la-DAP4StreamUnMarshaller.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DAP4StreamUnMarshaller.cc' object='libdap_la-DAP4StreamUnMarshaller.lo' libtool=yes @AMDEPBACKSLASH@
+libdap_la-D4StreamMarshaller.lo: D4StreamMarshaller.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-D4StreamMarshaller.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4StreamMarshaller.Tpo -c -o libdap_la-D4StreamMarshaller.lo `test -f 'D4StreamMarshaller.cc' || echo '$(srcdir)/'`D4StreamMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4StreamMarshaller.Tpo $(DEPDIR)/libdap_la-D4StreamMarshaller.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4StreamMarshaller.cc' object='libdap_la-D4StreamMarshaller.lo' libtool=yes @AMDEPBACKSLASH@
 @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-DAP4StreamUnMarshaller.lo `test -f 'DAP4StreamUnMarshaller.cc' || echo '$(srcdir)/'`DAP4StreamUnMarshaller.cc
+ 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-D4StreamMarshaller.lo `test -f 'D4StreamMarshaller.cc' || echo '$(srcdir)/'`D4StreamMarshaller.cc
+
+libdap_la-D4StreamUnMarshaller.lo: D4StreamUnMarshaller.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-D4StreamUnMarshaller.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4StreamUnMarshaller.Tpo -c -o libdap_la-D4StreamUnMarshaller.lo `test -f 'D4StreamUnMarshaller.cc' || echo '$(srcdir)/'`D4StreamUnMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4StreamUnMarshaller.Tpo $(DEPDIR)/libdap_la-D4StreamUnMarshaller.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4StreamUnMarshaller.cc' object='libdap_la-D4StreamUnMarshaller.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-D4StreamUnMarshaller.lo `test -f 'D4StreamUnMarshaller.cc' || echo '$(srcdir)/'`D4StreamUnMarshaller.cc
 
 libdap_la-Int64.lo: Int64.cc
 @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-Int64.lo -MD -MP -MF $(DEPDIR)/libdap_la-Int64.Tpo -c -o libdap_la-Int64.lo `test -f 'Int64.cc' || echo '$(srcdir)/'`Int64.cc
@@ -1751,13 +1833,6 @@ libdap_la-D4BaseTypeFactory.lo: D4BaseTypeFactory.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @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-D4BaseTypeFactory.lo `test -f 'D4BaseTypeFactory.cc' || echo '$(srcdir)/'`D4BaseTypeFactory.cc
 
-libdap_la-D4Maps.lo: D4Maps.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-D4Maps.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4Maps.Tpo -c -o libdap_la-D4Maps.lo `test -f 'D4Maps.cc' || echo '$(srcdir)/'`D4Maps.cc
- at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4Maps.Tpo $(DEPDIR)/libdap_la-D4Maps.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4Maps.cc' object='libdap_la-D4Maps.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-D4Maps.lo `test -f 'D4Maps.cc' || echo '$(srcdir)/'`D4Maps.cc
-
 libdap_la-D4Dimensions.lo: D4Dimensions.cc
 @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-D4Dimensions.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4Dimensions.Tpo -c -o libdap_la-D4Dimensions.lo `test -f 'D4Dimensions.cc' || echo '$(srcdir)/'`D4Dimensions.cc
 @am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4Dimensions.Tpo $(DEPDIR)/libdap_la-D4Dimensions.Plo
@@ -1765,12 +1840,12 @@ libdap_la-D4Dimensions.lo: D4Dimensions.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @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-D4Dimensions.lo `test -f 'D4Dimensions.cc' || echo '$(srcdir)/'`D4Dimensions.cc
 
-libdap_la-D4EnumDef.lo: D4EnumDef.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-D4EnumDef.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4EnumDef.Tpo -c -o libdap_la-D4EnumDef.lo `test -f 'D4EnumDef.cc' || echo '$(srcdir)/'`D4EnumDef.cc
- at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4EnumDef.Tpo $(DEPDIR)/libdap_la-D4EnumDef.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4EnumDef.cc' object='libdap_la-D4EnumDef.lo' libtool=yes @AMDEPBACKSLASH@
+libdap_la-D4EnumDefs.lo: D4EnumDefs.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-D4EnumDefs.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4EnumDefs.Tpo -c -o libdap_la-D4EnumDefs.lo `test -f 'D4EnumDefs.cc' || echo '$(srcdir)/'`D4EnumDefs.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4EnumDefs.Tpo $(DEPDIR)/libdap_la-D4EnumDefs.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4EnumDefs.cc' object='libdap_la-D4EnumDefs.lo' libtool=yes @AMDEPBACKSLASH@
 @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-D4EnumDef.lo `test -f 'D4EnumDef.cc' || echo '$(srcdir)/'`D4EnumDef.cc
+ 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-D4EnumDefs.lo `test -f 'D4EnumDefs.cc' || echo '$(srcdir)/'`D4EnumDefs.cc
 
 libdap_la-D4Group.lo: D4Group.cc
 @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-D4Group.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4Group.Tpo -c -o libdap_la-D4Group.lo `test -f 'D4Group.cc' || echo '$(srcdir)/'`D4Group.cc
@@ -1779,6 +1854,76 @@ libdap_la-D4Group.lo: D4Group.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @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-D4Group.lo `test -f 'D4Group.cc' || echo '$(srcdir)/'`D4Group.cc
 
+libdap_la-DMR.lo: DMR.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-DMR.lo -MD -MP -MF $(DEPDIR)/libdap_la-DMR.Tpo -c -o libdap_la-DMR.lo `test -f 'DMR.cc' || echo '$(srcdir)/'`DMR.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-DMR.Tpo $(DEPDIR)/libdap_la-DMR.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DMR.cc' object='libdap_la-DMR.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-DMR.lo `test -f 'DMR.cc' || echo '$(srcdir)/'`DMR.cc
+
+libdap_la-D4Attributes.lo: D4Attributes.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-D4Attributes.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4Attributes.Tpo -c -o libdap_la-D4Attributes.lo `test -f 'D4Attributes.cc' || echo '$(srcdir)/'`D4Attributes.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4Attributes.Tpo $(DEPDIR)/libdap_la-D4Attributes.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4Attributes.cc' object='libdap_la-D4Attributes.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-D4Attributes.lo `test -f 'D4Attributes.cc' || echo '$(srcdir)/'`D4Attributes.cc
+
+libdap_la-D4Enum.lo: D4Enum.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-D4Enum.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4Enum.Tpo -c -o libdap_la-D4Enum.lo `test -f 'D4Enum.cc' || echo '$(srcdir)/'`D4Enum.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4Enum.Tpo $(DEPDIR)/libdap_la-D4Enum.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4Enum.cc' object='libdap_la-D4Enum.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-D4Enum.lo `test -f 'D4Enum.cc' || echo '$(srcdir)/'`D4Enum.cc
+
+libdap_la-chunked_ostream.lo: chunked_ostream.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-chunked_ostream.lo -MD -MP -MF $(DEPDIR)/libdap_la-chunked_ostream.Tpo -c -o libdap_la-chunked_ostream.lo `test -f 'chunked_ostream.cc' || echo '$(srcdir)/'`chunked_ostream.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-chunked_ostream.Tpo $(DEPDIR)/libdap_la-chunked_ostream.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='chunked_ostream.cc' object='libdap_la-chunked_ostream.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-chunked_ostream.lo `test -f 'chunked_ostream.cc' || echo '$(srcdir)/'`chunked_ostream.cc
+
+libdap_la-chunked_istream.lo: chunked_istream.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-chunked_istream.lo -MD -MP -MF $(DEPDIR)/libdap_la-chunked_istream.Tpo -c -o libdap_la-chunked_istream.lo `test -f 'chunked_istream.cc' || echo '$(srcdir)/'`chunked_istream.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-chunked_istream.Tpo $(DEPDIR)/libdap_la-chunked_istream.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='chunked_istream.cc' object='libdap_la-chunked_istream.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-chunked_istream.lo `test -f 'chunked_istream.cc' || echo '$(srcdir)/'`chunked_istream.cc
+
+libdap_la-D4Sequence.lo: D4Sequence.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-D4Sequence.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4Sequence.Tpo -c -o libdap_la-D4Sequence.lo `test -f 'D4Sequence.cc' || echo '$(srcdir)/'`D4Sequence.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4Sequence.Tpo $(DEPDIR)/libdap_la-D4Sequence.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4Sequence.cc' object='libdap_la-D4Sequence.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-D4Sequence.lo `test -f 'D4Sequence.cc' || echo '$(srcdir)/'`D4Sequence.cc
+
+libdap_la-D4Maps.lo: D4Maps.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-D4Maps.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4Maps.Tpo -c -o libdap_la-D4Maps.lo `test -f 'D4Maps.cc' || echo '$(srcdir)/'`D4Maps.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4Maps.Tpo $(DEPDIR)/libdap_la-D4Maps.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4Maps.cc' object='libdap_la-D4Maps.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-D4Maps.lo `test -f 'D4Maps.cc' || echo '$(srcdir)/'`D4Maps.cc
+
+libdap_la-D4Opaque.lo: D4Opaque.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-D4Opaque.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4Opaque.Tpo -c -o libdap_la-D4Opaque.lo `test -f 'D4Opaque.cc' || echo '$(srcdir)/'`D4Opaque.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4Opaque.Tpo $(DEPDIR)/libdap_la-D4Opaque.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4Opaque.cc' object='libdap_la-D4Opaque.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-D4Opaque.lo `test -f 'D4Opaque.cc' || echo '$(srcdir)/'`D4Opaque.cc
+
+libdap_la-D4AsyncUtil.lo: D4AsyncUtil.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-D4AsyncUtil.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4AsyncUtil.Tpo -c -o libdap_la-D4AsyncUtil.lo `test -f 'D4AsyncUtil.cc' || echo '$(srcdir)/'`D4AsyncUtil.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4AsyncUtil.Tpo $(DEPDIR)/libdap_la-D4AsyncUtil.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4AsyncUtil.cc' object='libdap_la-D4AsyncUtil.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-D4AsyncUtil.lo `test -f 'D4AsyncUtil.cc' || echo '$(srcdir)/'`D4AsyncUtil.cc
+
+libdap_la-D4RValue.lo: D4RValue.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-D4RValue.lo -MD -MP -MF $(DEPDIR)/libdap_la-D4RValue.Tpo -c -o libdap_la-D4RValue.lo `test -f 'D4RValue.cc' || echo '$(srcdir)/'`D4RValue.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-D4RValue.Tpo $(DEPDIR)/libdap_la-D4RValue.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4RValue.cc' object='libdap_la-D4RValue.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-D4RValue.lo `test -f 'D4RValue.cc' || echo '$(srcdir)/'`D4RValue.cc
+
 libdapclient_la-RCReader.lo: RCReader.cc
 @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
 @am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdapclient_la-RCReader.Tpo $(DEPDIR)/libdapclient_la-RCReader.Plo
@@ -1828,6 +1973,13 @@ libdapclient_la-HTTPCacheTable.lo: HTTPCacheTable.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @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
 
+libdapclient_la-D4Connect.lo: D4Connect.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-D4Connect.lo -MD -MP -MF $(DEPDIR)/libdapclient_la-D4Connect.Tpo -c -o libdapclient_la-D4Connect.lo `test -f 'D4Connect.cc' || echo '$(srcdir)/'`D4Connect.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdapclient_la-D4Connect.Tpo $(DEPDIR)/libdapclient_la-D4Connect.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4Connect.cc' object='libdapclient_la-D4Connect.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-D4Connect.lo `test -f 'D4Connect.cc' || echo '$(srcdir)/'`D4Connect.cc
+
 libparsers_la-lex.das.lo: lex.das.cc
 @am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparsers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libparsers_la-lex.das.lo -MD -MP -MF $(DEPDIR)/libparsers_la-lex.das.Tpo -c -o libparsers_la-lex.das.lo `test -f 'lex.das.cc' || echo '$(srcdir)/'`lex.das.cc
 @am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libparsers_la-lex.das.Tpo $(DEPDIR)/libparsers_la-lex.das.Plo
@@ -1898,11 +2050,26 @@ getdap-getdap.obj: getdap.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @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`
 
+getdap4-getdap4.o: getdap4.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdap4_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT getdap4-getdap4.o -MD -MP -MF $(DEPDIR)/getdap4-getdap4.Tpo -c -o getdap4-getdap4.o `test -f 'getdap4.cc' || echo '$(srcdir)/'`getdap4.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/getdap4-getdap4.Tpo $(DEPDIR)/getdap4-getdap4.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='getdap4.cc' object='getdap4-getdap4.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdap4_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o getdap4-getdap4.o `test -f 'getdap4.cc' || echo '$(srcdir)/'`getdap4.cc
+
+getdap4-getdap4.obj: getdap4.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdap4_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT getdap4-getdap4.obj -MD -MP -MF $(DEPDIR)/getdap4-getdap4.Tpo -c -o getdap4-getdap4.obj `if test -f 'getdap4.cc'; then $(CYGPATH_W) 'getdap4.cc'; else $(CYGPATH_W) '$(srcdir)/getdap4.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/getdap4-getdap4.Tpo $(DEPDIR)/getdap4-getdap4.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='getdap4.cc' object='getdap4-getdap4.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdap4_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o getdap4-getdap4.obj `if test -f 'getdap4.cc'; then $(CYGPATH_W) 'getdap4.cc'; else $(CYGPATH_W) '$(srcdir)/getdap4.cc'; fi`
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
 clean-libtool:
 	-rm -rf .libs _libs
+	-rm -rf GNU/.libs GNU/_libs
 
 distclean-libtool:
 	-rm -f libtool config.lt
@@ -2252,9 +2419,6 @@ distdir: $(DISTFILES)
 	      || 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 -755 \
 		-exec chmod u+rwx,go+rx {} \; -o \
@@ -2420,6 +2584,8 @@ 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)
+	-rm -f GNU/$(DEPDIR)/$(am__dirstamp)
+	-rm -f GNU/$(am__dirstamp)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -2432,7 +2598,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
 
 distclean: distclean-recursive
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR) GNU/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-libtool distclean-tags
@@ -2482,7 +2648,7 @@ installcheck-am:
 maintainer-clean: maintainer-clean-recursive
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR) GNU/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -2515,19 +2681,18 @@ uninstall-man: uninstall-man1
 	clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \
 	clean-noinstLTLIBRARIES cscope cscopelist cscopelist-recursive \
 	ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
-	dist-hook dist-lzip 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-man1 install-pdf install-pdf-am \
-	install-pkgconfigDATA install-pkgincludeHEADERS install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs installdirs-am maintainer-clean \
+	dist-lzip 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-man1 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 \
@@ -2540,11 +2705,6 @@ uninstall-man: uninstall-man1
 %.1: %.man1
 	groff -t -e -mandoc -Tascii $< | col -bx > $@
 
-# Not nearly as clean as it could be, but this removes .svn directories
-# in subdirs.
-dist-hook:
-	rm -rf `find $(distdir) -name .svn`
-
 # Copy the generated grammar files to the 'grammarfiles' directory.
 .PHONY: grammarfiles
 grammarfiles: $(GRAM_SRC)
@@ -2569,6 +2729,7 @@ cccc:
 .PHONY: fortify
 fortify: $(BUILT_SOURCES)
 	(cd gl && sourceanalyzer -b @PACKAGE at -gl $(MAKE) $(MFLAGS) )
+	(cd d4_ce && sourceanalyzer -b @PACKAGE at -d4_ce $(MAKE) $(MFLAGS) )
 	sourceanalyzer -b @PACKAGE at -parsers $(MAKE) $(MFLAGS) libparsers.la
 	sourceanalyzer -b @PACKAGE@ $(MAKE) $(MFLAGS) libdap.la libdapserver.la libdapclient.la
 	sourceanalyzer -b @PACKAGE@ -scan -f @PACKAGE at -@PACKAGE_VERSION at .fpr
@@ -2578,9 +2739,10 @@ fortify: $(BUILT_SOURCES)
 # 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
+	( cd gl && $(MAKE) $(MFLAGS) )
+	( cd d4_ce && $(MAKE) $(MFLAGS) )
+	$(MAKE)  $(MFLAGS) libparsers.la
+	sourceanalyzer -b @PACKAGE@ $(MAKE) $(MFLAGS) libdap.la libdapserver.la libdapclient.la
 	sourceanalyzer -b @PACKAGE@ -scan -f @PACKAGE at -@PACKAGE_VERSION at .fpr
 
 # No longer used? jhrg 1/29/13
@@ -2654,8 +2816,9 @@ collect-coverage-data:
 Operators.h: ce_expr.tab.hh
 
 @USE_C99_TYPES_TRUE at dods-datatypes.h: dods-datatypes-static.h
+ at USE_C99_TYPES_TRUE@	cp -p $< dods-datatypes.h
 @USE_C99_TYPES_FALSE at dods-datatypes.h: dods-datatypes-config.h
-	cp -p $< dods-datatypes.h
+ at USE_C99_TYPES_FALSE@	cp -p $< dods-datatypes.h
 
 xdr-datatypes.h: xdr-datatypes-config.h
 	cp -p $< xdr-datatypes.h
diff --git a/NEWS b/NEWS
index ba78352..52dc5e6 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,34 @@
+News for version 3.14.0
+
+News for version 3.13.3
+
+Memory leak fix in RValue.cc - affects server function evaluation only.
+
+News for version 3.13.2
+
+Fixed a memory leak in the CE parser when evaluating server functions.
+
+News for version 3.13.1
+
+Fix for a unit-test that uses the default server at test.opendap.org. 
+This affects neither the API nor ABI of libdap; only the test baseline
+was changed.
+
+News for version 3.13.0
+
+Added a xml file to serve as input for the perl-based abi compatability 
+checker. Seems to be pretty slick; see abi-checker.xml.in for more info.
+
+Some updates - mostly addition of #include <unistd.h> - for OSX 10.9's
+clang compiler.
+
+News for version 3.12.1
+
+Fixed the behavior of Sequence::read_row() so that the documented
+semantics of read() are used. This will require changes in some of the
+handlers but does not change the libray's ABI. Handler's that don't
+need the new/corrected behavior can use version 3.12.0.
+
 News for version 3.12.0
 
 Moved server functions out of libdap; they are now stored in a BES module.
diff --git a/ObjectType.h b/ObjectType.h
index 553146a..0cef35a 100644
--- a/ObjectType.h
+++ b/ObjectType.h
@@ -4,7 +4,7 @@
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
 // Access Protocol.
 
-// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Copyright (c) 2002,2003,2013 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -29,11 +29,9 @@
 namespace libdap
 {
 
-/** When a version 2.x or greater DAP data server sends an object, it uses
+/** When a version 2.x or greater DAP data server sends an object, it may use
     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.
+    object contained in the response.
 
     <pre>
      enum ObjectType {
@@ -41,16 +39,19 @@ namespace libdap
        dods_das,
        dods_dds,
        dods_data,
+       dods_ddx,
+       dods_data_ddx,
        dods_error,
        web_error,
-       dods_ddx,
-       dap4_ddx,
+
+       dap4_dmr,
        dap4_data,
        dap4_error,
-       dap4_data_ddx
      };
      </pre>
 
+    @note If this is cjanged, update the char* array 'descrip' in mime_util.h.
+
     @brief The type of object in the stream coming from the data
     server.  */
 
@@ -59,13 +60,14 @@ enum ObjectType {
     dods_das,
     dods_dds,
     dods_data,
+    dods_ddx,	   	// This is the old XML DDS/DAS used prior to dap4
+    dods_data_ddx,	// This is used for caching data responses
     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
+
+    dap4_dmr,		// DAP4 metadata
+    dap4_data,		// The DMR with a data blob
+    dap4_error		// The error response for DAP4
 };
 
 } // namespace libdap
diff --git a/README b/README
index 2118519..8ab076b 100644
--- a/README
+++ b/README
@@ -1,3 +1,28 @@
+Updated for 3.13.3
+
+Bug fix release
+
+Updated for 3.13.2
+
+Bug fix release
+
+Updated for 3.13.1
+
+A test baseline was updated to use both the DAP2 and DAP4 version of
+the XDAP/X-DAP header. This change was likely over doing things on our
+part, but it's important to have the source releases pass all their
+tests.
+ 
+Updated 3.13.0
+
+Support for clang: Apple LLVM version 5.1 (clang-503.0.40) (based on
+LLVM 3.4svn) added.
+
+Updated for version 3.12.1
+
+Note that the documented behavior of BaseType::read() is now correctly
+implemented.
+
 Updated for version 3.12.0
 
 The server functions have been moved out of libdap and into their own 
diff --git a/README.dodsrc b/README.dodsrc
index 8f48059..011c7e2 100644
--- a/README.dodsrc
+++ b/README.dodsrc
@@ -1,4 +1,4 @@
-$Id: README.dodsrc 18646 2008-04-25 19:21:25Z jimg $
+$Id$
 
 Current for version 3.7.6 (12 March 2007)
 
diff --git a/RValue.cc b/RValue.cc
index bf8dab6..b753c1f 100644
--- a/RValue.cc
+++ b/RValue.cc
@@ -36,10 +36,6 @@
 
 #include "config.h"
 
-static char rcsid[] not_used =
-    {"$Id: RValue.cc 27197 2013-10-01 21:29:54Z jimg $"
-    };
-
 #include <cassert>
 #include <iostream>
 
@@ -138,6 +134,14 @@ rvalue::~rvalue()
     // 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.
+
+	// ADB: the d_args vector still needs to be deleted
+	if (d_args != 0) {
+		for (std::vector<rvalue *>::iterator iter = d_args->begin(); iter != d_args->end(); ++iter) {
+			delete *iter;
+		}
+		delete d_args;
+	}
 }
 
 string
diff --git a/RValue.h b/RValue.h
index 825fa35..2a408ba 100644
--- a/RValue.h
+++ b/RValue.h
@@ -32,6 +32,8 @@
 #ifndef _rvalue_h
 #define _rvalue_h
 
+#include <dods-datatypes.h>
+
 namespace libdap
 {
 
@@ -53,11 +55,11 @@ public:
     typedef std::vector<rvalue *>::const_iterator Args_citer ;
 
     rvalue(BaseType *bt);
-    rvalue(btp_func f, vector<rvalue *> *a);
+    rvalue(btp_func f, std::vector<rvalue *> *a);
     rvalue();
 
     virtual ~rvalue();
-    string value_name();
+    std::string value_name();
 
     BaseType *bvalue(DDS &dds);
 };
diff --git a/Response.h b/Response.h
index 7fd1549..4a90757 100644
--- a/Response.h
+++ b/Response.h
@@ -28,20 +28,11 @@
 
 #include <cstdio>
 #include <string>
+//#include <iostream>
+#include <fstream>
 
-#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
+#include "debug.h"
 
 namespace libdap
 {
@@ -57,36 +48,36 @@ namespace libdap
     @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
+    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;
+    std::fstream *d_cpp_stream;
+
     /// Response object type
     ObjectType d_type;
     /// Server version
-    string d_version;
+    std::string d_version;
     /// The DAP server's protocol
-    string d_protocol;
+    std::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");
-    }
+    Response(const Response &);
+    Response &operator=(const Response &);
     //@}
 
 public:
+    Response() : d_stream(0), d_cpp_stream(0), d_type(unknown_type),  d_version("dods/0.0"), d_protocol("2.0"),
+		d_status(0)
+	{ }
+
     /** 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
@@ -94,64 +85,42 @@ public:
 	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)
-    { }
+    Response(FILE *s, int status = 0) : d_stream(s), d_cpp_stream(0), d_type(unknown_type),
+            d_version("dods/0.0"), d_protocol("2.0"), d_status(status) { }
+
+    Response(std::fstream *s, int status = 0) : d_stream(0), d_cpp_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);
+        if (d_cpp_stream)
+        	d_cpp_stream->close();
     }
 
-    /** @name Accessors */
+    /** @name getters */
     //@{
-    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;
-    }
+    virtual int get_status() const {  return d_status; }
+    virtual FILE *get_stream() const { return d_stream; }
+    virtual std::istream *get_cpp_stream() const { return d_cpp_stream; }
+
+    virtual ObjectType get_type() const { return d_type; }
+    virtual std::string get_version() const { return d_version; }
+    virtual std::string get_protocol() const { return d_protocol; }
     //@}
 
-    /** @name Mutators */
+    /** @name setters */
     //@{
-    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;
-    }
+    virtual void set_status(int s) { d_status = s; }
+
+    virtual void set_stream(FILE *s) { d_stream = s; }
+    virtual void set_cpp_stream(std::istream *s) { d_cpp_stream = dynamic_cast<std::fstream*>(s); }
+
+    virtual void set_type(ObjectType o) { d_type = o; }
+    virtual void set_version(const std::string &v) { d_version = v; }
+    virtual void set_protocol(const std::string &p) { d_protocol = p; }
     //@}
 };
 
diff --git a/ResponseTooBigErr.cc b/ResponseTooBigErr.cc
index 8847427..e636a1f 100644
--- a/ResponseTooBigErr.cc
+++ b/ResponseTooBigErr.cc
@@ -26,10 +26,6 @@
 
 #include "config.h"
 
-static char rcsid[] not_used =
-    {"$Id: ResponseTooBigErr.cc 27197 2013-10-01 21:29:54Z jimg $"
-    };
-
 #include <string>
 
 #include "ResponseTooBigErr.h"
diff --git a/Sequence.cc b/Sequence.cc
index e6be993..bd2b13a 100644
--- a/Sequence.cc
+++ b/Sequence.cc
@@ -32,6 +32,8 @@
 //
 // jhrg 9/14/94
 
+//#define DODS_DEBUG
+//#define DODS_DEBUG2
 
 #include "config.h"
 
@@ -39,9 +41,6 @@
 #include <string>
 #include <sstream>
 
-//#define DODS_DEBUG
-//#define DODS_DEBUG2
-
 #include "Byte.h"
 #include "Int16.h"
 #include "UInt16.h"
@@ -69,6 +68,12 @@
 #include "InternalErr.h"
 #include "escaping.h"
 
+#include "D4Attributes.h"
+#include "D4Sequence.h"
+#include "D4Group.h"
+#include "Constructor.h"
+#include "DMR.h"
+
 using namespace std;
 
 namespace libdap {
@@ -78,9 +83,10 @@ static const unsigned char start_of_instance = 0x5A; // binary pattern 0101 1010
 
 // Private member functions
 
-void
-Sequence::m_duplicate(const Sequence &s)
+void Sequence::m_duplicate(const Sequence &s)
 {
+    DBG(cerr << "In Sequence::m_duplicate" << endl);
+
     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;
@@ -92,24 +98,16 @@ Sequence::m_duplicate(const Sequence &s)
 
     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++) {
+    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++) {
+        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);
@@ -119,35 +117,30 @@ Sequence::m_duplicate(const Sequence &s)
     }
 }
 
-static void
-write_end_of_sequence(Marshaller &m)
+static void write_end_of_sequence(Marshaller &m)
 {
-    m.put_opaque( (char *)&end_of_sequence, 1 ) ;
+    m.put_opaque((char *) &end_of_sequence, 1);
 }
 
-static void
-write_start_of_instance(Marshaller &m)
+static void write_start_of_instance(Marshaller &m)
 {
-    m.put_opaque( (char *)&start_of_instance, 1 ) ;
+    m.put_opaque((char *) &start_of_instance, 1);
 }
 
-static unsigned char
-read_marker(UnMarshaller &um)
+static unsigned char read_marker(UnMarshaller &um)
 {
     unsigned char marker;
-    um.get_opaque( (char *)&marker, 1 ) ;
+    um.get_opaque((char *) &marker, 1);
 
     return marker;
 }
 
-static bool
-is_start_of_instance(unsigned char marker)
+static bool is_start_of_instance(unsigned char marker)
 {
     return (marker == start_of_instance);
 }
 
-static bool
-is_end_of_sequence(unsigned char marker)
+static bool is_end_of_sequence(unsigned char marker)
 {
     return (marker == end_of_sequence);
 }
@@ -155,40 +148,38 @@ is_end_of_sequence(unsigned char marker)
 // 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.
+ 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.
+ @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)
-{}
+ @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)
-{}
+ 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)
+Sequence::Sequence(const Sequence &rhs) :
+        Constructor(rhs)
 {
     m_duplicate(rhs);
 }
@@ -199,40 +190,56 @@ Sequence::ptr_duplicate()
     return new Sequence(*this);
 }
 
-static inline void
-delete_bt(BaseType *bt_ptr)
+/**
+ * Build a D4Sequence from a DAP2 Sequence.
+ *
+ * Because DAP4 uses a different type for sequences, this code must
+ * be subclassed by anything other than trivial test code or client
+ * side-only uses of the library.
+ *
+ * @note This version of transformto_dap4() builds a new type of object,
+ * so it must be subclassed.
+ *
+ * @param root Use this as the environment for D4Dimensions
+ * @param container Load the result into this container
+ * @return The new D4Sequence
+ */
+BaseType *
+Sequence::transform_to_dap4(D4Group *root, Constructor *container)
 {
-    DBG2(cerr << "In delete_bt: " << bt_ptr << endl);
-    delete bt_ptr; bt_ptr = 0;
+    D4Sequence *dest = new D4Sequence(name());
+
+    Constructor::transform_to_dap4(root, dest);
+
+    dest->set_length(-1);
+    dest->set_parent(container);
+
+    return dest;
 }
 
-static inline void
-delete_rows(BaseTypeRow *bt_row_ptr)
+static inline void delete_bt(BaseType *bt_ptr)
 {
-    DBG2(cerr << "In delete_rows: " << bt_row_ptr << endl);
+    delete bt_ptr;
+    bt_ptr = 0;
+}
 
+static inline void delete_rows(BaseTypeRow *bt_row_ptr)
+{
     for_each(bt_row_ptr->begin(), bt_row_ptr->end(), delete_bt);
 
-    delete bt_row_ptr; bt_row_ptr = 0;
+    delete bt_row_ptr;
+    bt_row_ptr = 0;
 }
 
 Sequence::~Sequence()
 {
-    DBG2(cerr << "Entering Sequence::~Sequence" << endl);
-    for (Vars_iter i = d_vars.begin(); i != d_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;
+    if (this == &rhs) return *this;
 
     dynamic_cast<Constructor &>(*this) = rhs; // run Constructor=
 
@@ -244,14 +251,12 @@ Sequence::operator=(const Sequence &rhs)
 /**
  * The Sequence class will be streamlined for DAP4.
  */
-bool
-Sequence::is_dap2_only_type()
+bool Sequence::is_dap2_only_type()
 {
     return true;
 }
 
-string
-Sequence::toString()
+string Sequence::toString()
 {
     ostringstream oss;
 
@@ -266,24 +271,7 @@ Sequence::toString()
     return oss.str();
 }
 
-#if 0
-int
-Sequence::element_count(bool leaves)
-{
-    if (!leaves)
-        return d_vars.size();
-    else {
-        int i = 0;
-        for (Vars_iter iter = d_vars.begin(); iter != d_vars.end(); iter++) {
-            i += (*iter)->element_count(true);
-        }
-        return i;
-    }
-}
-#endif
-
-bool
-Sequence::is_linear()
+bool Sequence::is_linear()
 {
     bool linear = true;
     bool seq_found = false;
@@ -311,209 +299,53 @@ Sequence::is_linear()
     return linear;
 }
 
-#if 0
-void
-Sequence::set_send_p(bool state)
-{
-    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
-        (*i)->set_send_p(state);
-    }
-
-    BaseType::set_send_p(state);
-}
-
-void
-Sequence::set_read_p(bool state)
-{
-    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
-        (*i)->set_read_p(state);
-    }
-
-    BaseType::set_read_p(state);
-}
-#endif
-#if 0
-void
-Sequence::set_in_selection(bool state)
-{
-    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
-        (*i)->set_in_selection(state);
-    }
-
-    BaseType::set_in_selection(state);
-}
-#endif
-#if 0
-/** @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");
-    if (bt->is_dap4_only_type())
-        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Sequence.");
-
-    // 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);
-    d_vars.push_back(bt_copy);
-}
-
-/** @brief Adds a variable to the Sequence.
-
-    @note 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.
-    @note This method does not copy the BaseType object; the caller
-    must not free the pointer.
-
-    @param bt A pointer to the DAP2 type variable to add to this Sequence.
-    @param part defaults to nil */
-void
-Sequence::add_var_nocopy(BaseType *bt, Part)
-{
-    if (!bt)
-        throw InternalErr(__FILE__, __LINE__,
-                          "Cannot add variable: NULL pointer");
-    if (bt->is_dap4_only_type())
-        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Sequence.");
-
-    bt->set_parent(this);
-    d_vars.push_back(bt);
-}
-#endif
-#if 0
-// 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);
-}
-#endif
-#if 0
-BaseType *
-Sequence::m_leaf_match(const string &name, btp_stack *s)
-{
-    for (Vars_iter i = d_vars.begin(); i != d_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 = d_vars.begin(); i != d_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;
-}
-#endif
 /** @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. */
+ @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;
+    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)
+ 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 The SequenceValues object for this Sequence. */
+SequenceValues Sequence::value()
+{
+    return d_values;
+}
+
+/** Get the value for this sequence.
+ @return The SequenceValues object for this Sequence. */
+SequenceValues &
+Sequence::value_ref()
 {
     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 */
+ @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;
+    if (!bt_row_ptr) return 0;
 
     BaseTypeRow::iterator bt_row_iter = bt_row_ptr->begin();
     BaseTypeRow::iterator bt_row_end = bt_row_ptr->end();
@@ -527,102 +359,131 @@ Sequence::var_value(size_t row, const string &name)
 }
 
 /** @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 */
+ @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 (!bt_row_ptr) return 0;
 
-    if (i >= bt_row_ptr->size())
-        return 0;
+    if (i >= bt_row_ptr->size()) return 0;
 
     return (*bt_row_ptr)[i];
 }
 
-#if 0
-unsigned int
-Sequence::width()
-{
-    unsigned int sz = 0;
-
-    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
-        sz += (*i)->width();
-    }
-
-    return sz;
-}
-
-/** This version of width simply returns the same thing as width() for simple
-    types and Arrays. For Sequence it returns the total row size if constrained
-    is false, or the size of the row elements in the current projection if true.
-
-    @param constrained If true, return the size after applying a constraint.
-    @return  The number of bytes used by the variable.
- */
-unsigned int
-Sequence::width(bool constrained)
-{
-    unsigned int sz = 0;
-
-    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
-    	if (constrained) {
-    		if ((*i)->send_p())
-    			sz += (*i)->width(constrained);
-    	}
-    	else {
-    		sz += (*i)->width(constrained);
-    	}
-    }
-
-    return sz;
-}
-#endif
-
 // 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 expression (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 implementation 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()
+ 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 expression (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 implementation 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() const
 {
     return -1;
 }
 
-
-int
-Sequence::number_of_rows()
+// Hmmm. how is this different from length()?
+int Sequence::number_of_rows() const
 {
     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()
+ 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;
 }
 
+#if 0
+// written but not used - this was written so that values loaded from
+// Arrays into a new ('synthesized') sequence by the 'tablar() server
+// function would be properly used during the evaluation of a selection
+// expression. But I forgot that tabular() uses a specialized version of
+// Sequence: TabularSequence and that has it's own version of serialize().
+// To get the returnAs="ascii" to filter values, I also need to specialize
+// the intern_data() method of Sequence. jhrg 3/9/15
+
+/**
+ * Protected method to be used when a Sequence has values loaded in from
+ * someplace like a function and will never need to use the read() method.
+ * This transfers the ith value from the SequenceValues object that holds
+ * the complete set of values for the Sequence into the prototype variables
+ * (which are scalars) so that evaluation of the selection operation can
+ * proceed correctly.
+ *
+ * @note The vector<>.at() method is quite a bit slower than the [] access;
+ * refactor this once were done testing.
+ *
+ * @param row_number Transfer this row's data values. Could use the object's
+ * d_row_number field.
+ */
+void Sequence::load_prototypes_with_values(int row_number)
+{
+    vector<BaseType*> *row = d_values.at(row_number);
+
+    // For each of the prototype variables in the Sequence, load it
+    // with a values from the BaseType* vector. The order should match.
+    // Test the type, but assume if that matches, the value is correct
+    // for the variable.
+    int pos = 0;
+    for (Vars_iter i = var_begin(), e = var_end(); i != e; ++i) {
+        if ((*i)->type() != row->at(pos)->var()->type())
+            throw InternalErr(__FILE__, __LINE__, "Expected types to match when loading values for selection expression evaluation.");
+
+        // Ugly...
+        switch ((*i)->type()) {
+        case dods_byte_c:
+            static_cast<Byte*>(*i)->set_value(static_cast<Byte*>(row->at(pos++))->value());
+            break;
+        case dods_int16_c:
+            static_cast<Int16*>(*i)->set_value(static_cast<Int16*>(row->at(pos++))->value());
+            break;
+        case dods_int32_c:
+            static_cast<Int32*>(*i)->set_value(static_cast<Int32*>(row->at(pos++))->value());
+            break;
+        case dods_uint16_c:
+            static_cast<UInt16*>(*i)->set_value(static_cast<UInt16*>(row->at(pos++))->value());
+            break;
+        case dods_uint32_c:
+            static_cast<UInt32*>(*i)->set_value(static_cast<UInt32*>(row->at(pos++))->value());
+            break;
+        case dods_float32_c:
+            static_cast<Float32*>(*i)->set_value(static_cast<Float32*>(row->at(pos++))->value());
+            break;
+        case dods_float64_c:
+            static_cast<Float64*>(*i)->set_value(static_cast<Float64*>(row->at(pos++))->value());
+            break;
+        case dods_str_c:
+            static_cast<Str*>(*i)->set_value(static_cast<Str*>(row->at(pos++))->value());
+            break;
+        case dods_url_c:
+            static_cast<Url*>(*i)->set_value(static_cast<Url*>(row->at(pos++))->value());
+            break;
+        default:
+            throw InternalErr(__FILE__, __LINE__, "Expected a scalar type when loading values for selection expression evaluation.");
+        }
+    }
+}
+
+#endif
+
 // Notes:
 // Assume that read() is implemented so that, when reading data for a nested
 // sequence, only the outer most level is *actually* read.
@@ -644,66 +505,72 @@ Sequence::reset_row_number()
 // 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)
+ 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;
+    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 false;
     }
 
     dds.timeout_on();
 
-    int eof = 0;  // Start out assuming EOF is false.
+    bool eof = false;  // Start out assuming EOF is false.
     while (!eof && d_row_number < row) {
         if (!read_p()) {
-            eof = (read() == false);
+            // jhrg original version from 10/9/13 : eof = (read() == false);
+            eof = read();
         }
+#if 0
+        // A change (3/9/15): I've made the is_synthesized property
+        // work so that the prototype variables in the Sequence are loaded
+        // with the scalar values for the ith row so that the eval_selection()
+        // method will function correctly.
+
+        // See note above
 
+        if (d_is_synthesized) {
+            load_prototypes_with_values(d_row_number);
+        }
+#endif
         // 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++;
+        if (!eof && (!ce_eval || eval.eval_selection(dds, dataset()))) d_row_number++;
 
         set_read_p(false); // ...so that the next instance will be read
     }
@@ -717,9 +584,8 @@ Sequence::read_row(int row, DDS &dds,
     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;
+    DBG2(cerr << "Leaving Sequence::read_row for " << name() << " with eof: " << eof << endl);
+    return !eof; // jhrg 10/10/13 was: eof == 0;
 }
 
 // Private. This is used to process constraints on the rows of a sequence.
@@ -729,75 +595,72 @@ Sequence::read_row(int row, DDS &dds,
 // 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)
+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 satisfies a CE, the empty Sequence is signaled 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)
+ 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 satisfies a CE, the empty Sequence is signaled 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);
 
@@ -812,9 +675,7 @@ Sequence::serialize(ConstraintEvaluator &eval, DDS &dds,
 // 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)
+bool Sequence::serialize_parent_part_one(DDS &dds, ConstraintEvaluator &eval, Marshaller &m)
 {
     DBG2(cerr << "Entering serialize_parent_part_one for " << name() << endl);
 
@@ -844,8 +705,7 @@ Sequence::serialize_parent_part_one(DDS &dds,
             // 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);
+            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
@@ -878,15 +738,12 @@ Sequence::serialize_parent_part_one(DDS &dds,
 //
 // 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)
+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)
-        static_cast<Sequence&>(*btp).serialize_parent_part_two(dds, eval, m);
+    if (btp && btp->type() == dods_sequence_c) static_cast<Sequence&>(*btp).serialize_parent_part_two(dds, eval, m);
 
     if (d_unsent_data) {
         DBG(cerr << "Writing Start of Instance marker" << endl);
@@ -897,7 +754,7 @@ Sequence::serialize_parent_part_two(DDS &dds,
         for (Vars_iter iter = d_vars.begin(); iter != d_vars.end(); iter++) {
             // Send all the non-sequence variables
             DBG(cerr << "Sequence::serialize_parent_part_two(), serializing "
-                << (*iter)->name() << endl);
+                    << (*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);
@@ -910,9 +767,7 @@ Sequence::serialize_parent_part_two(DDS &dds,
 
 // 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)
+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;
@@ -931,14 +786,10 @@ Sequence::serialize_leaf(DDS &dds,
     // 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.
+    // Sequence that really is the parent of a leaf sequence.
     if (status && !is_end_of_rows(i)) {
         BaseType *btp = get_parent();
-        if (btp && btp->type() == dods_sequence_c)
-            static_cast<Sequence&>(*btp).serialize_parent_part_two(dds,
-								    eval, m);
+        if (btp && btp->type() == dods_sequence_c) static_cast<Sequence&>(*btp).serialize_parent_part_two(dds, eval, m);
     }
 
     d_wrote_soi = false;
@@ -952,7 +803,7 @@ Sequence::serialize_leaf(DDS &dds,
         // In this loop serialize will signal an error with an exception.
         for (Vars_iter iter = d_vars.begin(); iter != d_vars.end(); iter++) {
             DBG(cerr << "Sequence::serialize_leaf(), serializing "
-                << (*iter)->name() << endl);
+                    << (*iter)->name() << endl);
             if ((*iter)->send_p()) {
                 DBG(cerr << "Send P is true, sending " << (*iter)->name() << endl);
                 (*iter)->serialize(eval, dds, m, false);
@@ -976,49 +827,44 @@ Sequence::serialize_leaf(DDS &dds,
 }
 
 /** 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 constraint evaluator
-    @param dds This DDS holds the variables for the data source */
-void
-Sequence::intern_data(ConstraintEvaluator &eval, DDS &dds)
+ 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 constraint 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);
+    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
+    // Sequences nested 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);
+            << ") 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)
+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);
 
@@ -1028,11 +874,8 @@ Sequence::intern_data_private(ConstraintEvaluator &eval,
         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)
+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);
 
@@ -1050,19 +893,15 @@ Sequence::intern_data_parent_part_one(DDS & dds,
     // selected because of a constraint evaluation. In either case, no
     // nested sequence d_values are pushed 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() ;
+    SequenceValues::size_type orig_stack_size = sequence_values_stack.size();
 
-    while (status
-           && (get_ending_row_number() == -1
-               || i <= get_ending_row_number()))
-    {
+    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:
-                	static_cast<Sequence&>(**iter).intern_data_private(
-                            eval, dds, sequence_values_stack);
+                    static_cast<Sequence&>(**iter).intern_data_private(eval, dds, sequence_values_stack);
                     break;
 
                 default:
@@ -1084,26 +923,21 @@ Sequence::intern_data_parent_part_one(DDS & dds,
     // 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);
+    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)
+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) {
-    	static_cast<Sequence&>(*btp).intern_data_parent_part_two(
-                                      dds, eval, sequence_values_stack);
+        static_cast<Sequence&>(*btp).intern_data_parent_part_two(dds, eval, sequence_values_stack);
     }
 
     DBG2(cerr << "    stack size: " << sequence_values_stack.size() << endl);
@@ -1122,14 +956,14 @@ Sequence::intern_data_parent_part_two(DDS &dds,
             else if ((*iter)->send_p()) { //Sequence; must be the last variable
                 Sequence *tmp = dynamic_cast<Sequence*>((*iter)->ptr_duplicate());
                 if (!tmp) {
-                	delete row_data;
+                    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);
+                        << " (" << &(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.
@@ -1138,17 +972,13 @@ Sequence::intern_data_parent_part_two(DDS &dds,
         }
 
         DBG2(cerr << "    pushing values for " << name()
-	          << " to " << values << endl);
+                << " to " << values << endl);
         values->push_back(row_data);
         set_unsent_data(false);
-    }
-    DBG(cerr << "Leaving intern_data_parent_part_two for " << name() << endl);
+    } 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)
+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);
 
@@ -1156,8 +986,7 @@ Sequence::intern_data_for_leaf(DDS &dds,
 
     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);
+    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();
@@ -1165,8 +994,7 @@ Sequence::intern_data_for_leaf(DDS &dds,
             // 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.
-        	static_cast<Sequence&>(*btp).intern_data_parent_part_two(
-					    dds, eval, sequence_values_stack);
+            static_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
@@ -1175,8 +1003,7 @@ Sequence::intern_data_for_leaf(DDS &dds,
         SequenceValues *values = sequence_values_stack.top();
         DBG2(cerr << "    using values = " << values << endl);
 
-        while (status && (get_ending_row_number() == -1
-                          || i <= get_ending_row_number())) {
+        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
@@ -1188,7 +1015,7 @@ Sequence::intern_data_for_leaf(DDS &dds,
             }
 
             DBG2(cerr << "    pushing values for " << name()
-	              << " to " << values << endl);
+                    << " to " << values << endl);
             // Save the row_data to values().
             values->push_back(row_data);
 
@@ -1198,47 +1025,45 @@ Sequence::intern_data_for_leaf(DDS &dds,
         }
 
         DBG2(cerr << "    popping d_values (" << sequence_values_stack.top()
-             << ") off stack; size: " << sequence_values_stack.size() << endl);
+                << ") off stack; size: " << sequence_values_stack.size() << endl);
         sequence_values_stack.pop();
-    }
-    DBG(cerr << "Leaving intern_data_for_leaf for " << name() << endl);
+    } 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 deserialize() 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)
+ 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 deserialize() 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!");
+    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);
+            << 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.");
+        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) {
@@ -1249,15 +1074,14 @@ Sequence::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
         else if (is_start_of_instance(marker)) {
             d_row_number++;
             DBG2(cerr << "Reading row " << d_row_number << " of "
-                 << name() << endl);
+                    << name() << endl);
             BaseTypeRow *bt_row_ptr = new BaseTypeRow;
             // Read the instance's values, building up the row
             for (Vars_iter iter = d_vars.begin(); iter != d_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_ptr << ") = "); DBG2(bt_ptr->print_val(stderr, ""));
                 bt_row_ptr->push_back(bt_ptr);
             }
             // Append this row to those accumulated.
@@ -1273,113 +1097,81 @@ Sequence::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
 // 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()
+ 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.
+ 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.
+ 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()
+ @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()
+ 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 ending 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)
+ 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 ending 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.");
+    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;
 }
 
-#if 0
-/** 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);
-}
-#endif
-
-void
-Sequence::print_one_row(FILE *out, int row, string space,
-                        bool print_row_num)
+void Sequence::print_one_row(FILE *out, int row, string space, bool print_row_num)
 {
     ostringstream oss;
     print_one_row(oss, row, space, print_row_num);
     fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
 }
 
-void
-Sequence::print_one_row(ostream &out, int row, string space,
-                        bool print_row_num)
+void Sequence::print_one_row(ostream &out, int row, string space, bool print_row_num)
 {
-    if (print_row_num)
-	out << "\n" << space << row << ": " ;
+    if (print_row_num) out << "\n" << space << row << ": ";
 
-    out << "{ " ;
+    out << "{ ";
 
     int elements = element_count();
     int j = 0;
@@ -1395,8 +1187,7 @@ Sequence::print_one_row(ostream &out, int row, string space,
         bt_ptr = var_value(row, j++);
         if (bt_ptr) {  // data
             if (bt_ptr->type() == dods_sequence_c)
-            	static_cast<Sequence*>(bt_ptr)->print_val_by_rows
-                     (out, space + "    ", false, print_row_num);
+                static_cast<Sequence*>(bt_ptr)->print_val_by_rows(out, space + "    ", false, print_row_num);
             else
                 bt_ptr->print_val(out, space, false);
         }
@@ -1408,121 +1199,89 @@ Sequence::print_one_row(ostream &out, int row, string space,
         if (bt_ptr) {  // data
             out << ", ";
             if (bt_ptr->type() == dods_sequence_c)
-            	static_cast<Sequence*>(bt_ptr)->print_val_by_rows
-                        (out, space + "    ", false, print_row_num);
+                static_cast<Sequence*>(bt_ptr)->print_val_by_rows(out, space + "    ", false, print_row_num);
             else
                 bt_ptr->print_val(out, space, false);
         }
     }
 
-    out << " }" ;
+    out << " }";
 }
 
-void
-Sequence::print_val_by_rows(FILE *out, string space, bool print_decl_p,
-                            bool print_row_numbers)
+void Sequence::print_val_by_rows(FILE *out, string space, bool print_decl_p, bool print_row_numbers)
 {
     ostringstream oss;
     print_val_by_rows(oss, space, print_decl_p, print_row_numbers);
     fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
 }
 
-void
-Sequence::print_val_by_rows(ostream &out, string space, bool print_decl_p,
-                            bool print_row_numbers)
+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 << " = ";
     }
 
-    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 << ", " ;
+        out << ", ";
     }
     print_one_row(out, i, space, print_row_numbers);
 
-    out << " }" ;
+    out << " }";
 
-    if (print_decl_p)
-	out << ";\n" ;
+    if (print_decl_p) out << ";\n";
 }
 
-void
-Sequence::print_val(FILE *out, string space, bool print_decl_p)
+void Sequence::print_val(FILE *out, string space, bool print_decl_p)
 {
     print_val_by_rows(out, space, print_decl_p, false);
 }
 
-void
-Sequence::print_val(ostream &out, string space, bool print_decl_p)
+void Sequence::print_val(ostream &out, string space, bool print_decl_p)
 {
     print_val_by_rows(out, space, print_decl_p, false);
 }
 
-#if 0
-bool
-Sequence::check_semantics(string &msg, bool all)
-{
-    if (!BaseType::check_semantics(msg))
-        return false;
-
-    if (!unique_names(d_vars, name(), type_name(), msg))
-        return false;
-
-    if (all)
-        for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
-            if (!(*i)->check_semantics(msg, true)) {
-                return false;
-            }
-        }
-
-    return true;
-}
-#endif
-
-void
-Sequence::set_leaf_p(bool state)
+void Sequence::set_leaf_p(bool state)
 {
     d_leaf_sequence = state;
 }
 
-bool
-Sequence::is_leaf_sequence()
+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 effectively hidden from the
-    serialization and evaluation code (see the documentation 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)
+ 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 effectively hidden from the
+ serialization and evaluation code (see the documentation 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;
 
@@ -1538,13 +1297,14 @@ Sequence::set_leaf_sequence(int lvl)
         // 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.");
+                throw Error(
+                        "This implementation does not support more than one nested sequence at a level. Contact the server administrator.");
 
             has_child_sequence = true;
             static_cast<Sequence&>(**iter).set_leaf_sequence(++lvl);
         }
         else if ((*iter)->type() == dods_structure_c) {
-        	static_cast<Structure&>(**iter).set_leaf_sequence(lvl);
+            static_cast<Structure&>(**iter).set_leaf_sequence(lvl);
         }
     }
 
@@ -1564,31 +1324,24 @@ Sequence::set_leaf_sequence(int lvl)
  * @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() ;
+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
index 26bbd27..ea2da32 100644
--- a/Sequence.h
+++ b/Sequence.h
@@ -42,318 +42,265 @@
 #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
 
 #ifndef S_XDRUtils_h
 #include "XDRUtils.h"
 #endif
 
-namespace libdap
-{
+namespace libdap {
+
+class BaseType;
+class ConstraintEvaluator;
+class D4Group;
 
 /** The type BaseTypeRow is used to store single rows of values in an
-    instance of Sequence. Values are stored in instances of BaseType. */
+ 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
-{
+ 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 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;
-#if 0
-    BaseType *m_leaf_match(const string &name, btp_stack *s = 0);
-    BaseType *m_exact_match(const string &name, btp_stack *s = 0);
-#endif
-    bool is_end_of_rows(int i);
+	// This holds the values read off the wire. Values are stored in
+	// instances of BaseTypeRow objects which hold instances of BaseType.
+	SequenceValues d_values;
 
-    friend class SequenceTest;
+	// The number of the row that has just been deserialized. Before
+	// deserialized has been called, this field is -1.
+	int d_row_number;
 
-protected:
-    void m_duplicate(const Sequence &s);
-    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);
+	// 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;
 
-public:
+	// Used to track if data has not already been sent.
+	bool d_unsent_data;
 
-    Sequence(const string &n);
-    Sequence(const string &n, const string &d);
+	// 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;
 
-    Sequence(const Sequence &rhs);
+	// This signals whether the sequence is a leaf or parent.
+	bool d_leaf_sequence;
 
-    virtual ~Sequence();
+	// In a hierarchy of sequences, is this the top most?
+	bool d_top_most;
 
-    Sequence &operator=(const Sequence &rhs);
+	bool is_end_of_rows(int i);
 
-    virtual BaseType *ptr_duplicate();
+	friend class SequenceTest;
 
-    virtual bool is_dap2_only_type();
+protected:
+	void m_duplicate(const Sequence &s);
+	typedef stack<SequenceValues*> sequence_values_stack_t;
 
-    virtual string toString();
-#if 0
-    virtual int element_count(bool leaves = false);
-#endif
-    virtual bool is_linear();
-#if 0
-    virtual void set_send_p(bool state);
-    virtual void set_read_p(bool state);
-#endif
-#if 0
-    virtual void set_in_selection(bool state);
-#endif
+	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);
 #if 0
-    virtual unsigned int width(bool constrained = false);
-    virtual unsigned int width(bool constrained);
+	// See note in Sequence.cc
+        virtual void load_prototypes_with_values(int d_row_number);
 #endif
 
-    virtual int length();
+public:
 
-    virtual int number_of_rows();
+	Sequence(const string &n);
+	Sequence(const string &n, const string &d);
 
-    virtual bool read_row(int row, DDS &dds,
-                          ConstraintEvaluator &eval, bool ce_eval = true);
+	Sequence(const Sequence &rhs);
 
-    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 ~Sequence();
 
-    /// Rest the row number counter
-    void reset_row_number();
+	Sequence &operator=(const Sequence &rhs);
 
-    int get_starting_row_number();
+	virtual BaseType *ptr_duplicate();
 
-    virtual int get_row_stride();
+	virtual BaseType *transform_to_dap4(D4Group *root, Constructor *container);
 
-    virtual int get_ending_row_number();
+	virtual bool is_dap2_only_type();
 
-    virtual void set_row_number_constraint(int start, int stop, int stride = 1);
+	virtual string toString();
 
-    /// Get the unsent data property
-    bool get_unsent_data()
-    {
-        return d_unsent_data;
-    }
+	virtual bool is_linear();
 
-    /// Set the unsent data property
-    void set_unsent_data(bool usd)
-    {
-        d_unsent_data = usd;
-    }
+	virtual int length() const;
 
-#if 0
-    // Move me!
-    virtual unsigned int val2buf(void *val, bool reuse = false);
-    virtual unsigned int buf2val(void **val);
-#endif
+	virtual int number_of_rows() const;
 
-    virtual void set_value(SequenceValues &values);
-    virtual SequenceValues value();
-#if 0
-    virtual BaseType *var(const string &name, bool exact_match = true,btp_stack *s = 0);
-    virtual BaseType *var(const string &n, btp_stack &s);
-#endif
+	virtual bool read_row(int row, DDS &dds, ConstraintEvaluator &eval, bool ce_eval = true);
 
-    virtual BaseType *var_value(size_t row, const string &name);
+	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 BaseType *var_value(size_t row, size_t i);
+	/// Rest the row number counter
+	void reset_row_number();
 
-    virtual BaseTypeRow *row_value(size_t row);
-#if 0
-    virtual void add_var(BaseType *, Part part = nil);
-    virtual void add_var_nocopy(BaseType *, Part part = nil);
-#endif
-    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);
-
-    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);
-#if 0
-    virtual bool check_semantics(string &msg, bool all = false);
-#endif
-    virtual void set_leaf_p(bool state);
+	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;
+	}
+
+	virtual void set_value(SequenceValues &values);
+	virtual SequenceValues value();
+	virtual SequenceValues &value_ref();
+
+	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 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);
+
+	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);
+
+	virtual void set_leaf_p(bool state);
 
-    virtual bool is_leaf_sequence();
+	virtual bool is_leaf_sequence();
 
-    virtual void set_leaf_sequence(int lvl = 1);
+	virtual void set_leaf_sequence(int lvl = 1);
 
-    virtual void dump(ostream &strm) const ;
+	virtual void dump(ostream &strm) const;
 };
 
 } // namespace libdap
diff --git a/ServerFunction.cc b/ServerFunction.cc
index 6f83ee5..2558804 100644
--- a/ServerFunction.cc
+++ b/ServerFunction.cc
@@ -29,23 +29,26 @@
  *      Author: ndp
  */
 
+#include "config.h"
+
 #include "ServerFunction.h"
 
+using namespace std;
+
 namespace libdap {
 
-ServerFunction::ServerFunction() {
+ServerFunction::ServerFunction() : d_bool_func(0), d_btp_func(0), d_proj_func(0), d_d4_function(0)
+{
 	setName("abstract_function");
 	setDescriptionString("This function does nothing.");
 	setUsageString("You can't use this function");
 	setRole("http://services.opendap.org/dap4/server-side-function/null");
 	setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions");
-    d_bool_func = 0;
-	d_btp_func  = 0;
-	d_proj_func = 0;
-
 }
 
-ServerFunction::ServerFunction(string name, string version, string description, string usage, string doc_url, string role, bool_func f){
+ServerFunction::ServerFunction(string name, string version, string description, string usage, string doc_url,
+		string role, bool_func f) : d_bool_func(0), d_btp_func(0), d_proj_func(0), d_d4_function(0)
+{
 	setName(name);
 	setVersion(version);
 	setDescriptionString(description);
@@ -55,7 +58,9 @@ ServerFunction::ServerFunction(string name, string version, string description,
 	setFunction(f);
 }
 
-ServerFunction::ServerFunction(string name, string version, string description, string usage, string doc_url, string role, btp_func f){
+ServerFunction::ServerFunction(string name, string version, string description, string usage, string doc_url,
+		string role, btp_func f) : d_bool_func(0), d_btp_func(0), d_proj_func(0), d_d4_function(0)
+{
 	setName(name);
 	setVersion(version);
 	setDescriptionString(description);
@@ -66,7 +71,9 @@ ServerFunction::ServerFunction(string name, string version, string description,
 
 }
 
-ServerFunction::ServerFunction(string name, string version, string description, string usage, string doc_url, string role, proj_func f){
+ServerFunction::ServerFunction(string name, string version, string description, string usage, string doc_url,
+		string role, proj_func f) : d_bool_func(0), d_btp_func(0), d_proj_func(0), d_d4_function(0)
+{
 	setName(name);
 	setVersion(version);
 	setDescriptionString(description);
@@ -76,13 +83,16 @@ ServerFunction::ServerFunction(string name, string version, string description,
 	setFunction(f);
 }
 
-
-ServerFunction::~ServerFunction() {
-    d_bool_func = 0;
-	d_btp_func  = 0;
-	d_proj_func = 0;
+ServerFunction::ServerFunction(string name, string version, string description, string usage, string doc_url,
+		string role, D4Function f) : d_bool_func(0), d_btp_func(0), d_proj_func(0), d_d4_function(0)
+{
+	setName(name);
+	setVersion(version);
+	setDescriptionString(description);
+	setUsageString(usage);
+	setRole(role);
+	setDocUrl(doc_url);
+	setFunction(f);
 }
 
-
-
 } /* namespace libdap */
diff --git a/ServerFunction.h b/ServerFunction.h
index b2b90c7..8898b2a 100644
--- a/ServerFunction.h
+++ b/ServerFunction.h
@@ -23,69 +23,74 @@
 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
 /*
- * AbstractFunction.h
+ * ServerFunction.h
  *
  *  Created on: Feb 2, 2013
  *      Author: ndp
  */
 
-#ifndef ABSTRACTFUNCTION_H_
-#define ABSTRACTFUNCTION_H_
+#ifndef SERVER_FUNCTION_H_
+#define SERVER_FUNCTION_H_
 
 #include <iostream>
-#include "expr.h"
 
-using std::endl;
-
-#include "BaseType.h"
+#include <expr.h>
+#include <D4Function.h>
 
 namespace libdap {
 
-
 class ServerFunction {
 
 private:
-    string name;
-    string description;
-    string usage;
-    string doc_url; // @TODO 'doc_url' Should be a URL object.
-    string role;    // @TODO 'role' Should be a URI object.
-    string version;
+    std::string name;
+    std::string description;
+    std::string usage;
+    std::string doc_url;
+    std::string role;
+    std::string version;
 
-    libdap::bool_func d_bool_func;
-    libdap::btp_func  d_btp_func;
-    libdap::proj_func d_proj_func;
+    // These are typedefs from DAP2 that are used with its CE parser
+    // and are found in expr.h. jhrg 3/10/14
+    bool_func d_bool_func;
+    btp_func  d_btp_func;
+    proj_func d_proj_func;
+
+    D4Function d_d4_function;
 
 public:
     ServerFunction();
-    ServerFunction(string name, string version, string description, string usage, string doc_url, string role, bool_func f);
-    ServerFunction(string name, string version, string description, string usage, string doc_url, string role, btp_func f);
-    ServerFunction(string name, string version, string description, string usage, string doc_url, string role, proj_func f);
-    virtual ~ServerFunction();
-
+    ServerFunction(std::string name, std::string version, std::string description, std::string usage,
+    		std::string doc_url, std::string role, bool_func f);
+    ServerFunction(std::string name, std::string version, std::string description, std::string usage,
+    		std::string doc_url, std::string role, btp_func f);
+    ServerFunction(std::string name, std::string version, std::string description, std::string usage,
+    		std::string doc_url, std::string role, proj_func f);
+    ServerFunction(std::string name, std::string version, std::string description, std::string usage,
+    		std::string doc_url, std::string role, D4Function f);
 
+    virtual ~ServerFunction() {	}
 
-	string getName() { return name; }
-	void   setName(const string &n){ name = n; }
+	std::string getName() { return name; }
+	void setName(const std::string &n){ name = n; }
 
-	string getUsageString() { return usage; }
-	void   setUsageString(const string &u){ usage = u; }
+	std::string getUsageString() { return usage; }
+	void setUsageString(const std::string &u){ usage = u; }
 
-	string getDocUrl() { return doc_url; }
-	void   setDocUrl(const string &url){ doc_url = url; }
+	std::string getDocUrl() { return doc_url; }
+	void setDocUrl(const std::string &url){ doc_url = url; }
 
-	string getRole() { return role; }
-	void   setRole(const string &r){ role = r; }
+	std::string getRole() { return role; }
+	void setRole(const std::string &r){ role = r; }
 
-	string getDescriptionString(){ return description; }
-	void   setDescriptionString(const string &desc){ description = desc; }
+	std::string getDescriptionString(){ return description; }
+	void setDescriptionString(const std::string &desc){ description = desc; }
 
-	string getVersion(){ return version; }
-	void   setVersion(const string &ver){ version = ver; }
+	std::string getVersion(){ return version; }
+	void setVersion(const std::string &ver){ version = ver; }
 
 	/**
 	 * If you are writing a function that can only operate on a particular kind of data, or one that relies on the presence
-	 * of particular metadata, then you might orride this method in order to stop the server from
+	 * of particular metadata, then you might override this method in order to stop the server from
 	 * advertising the function in conjunction with datasets to which it cannot be applied.
 	 *
 	 * @param dds A DDS object for the dataset about which we will ask the question:
@@ -97,40 +102,50 @@ public:
 	 */
 	virtual bool canOperateOn(DDS &) { return true; }
 
-	void setFunction(bool_func bf){
+	/**
+	 * @see canOperateOn(DDS &)
+	 * @param The Dataset's DMR.
+	 * @return True if the function can work with the dataset, false otherwise.
+	 */
+	virtual bool canOperateOn(DMR &) { return true; }
+
+	/**
+	 * Set the C function pointer for this function object.
+	 * @note This does not alter any of the other function pointers,
+	 * so the same name can be used for all four different kinds of
+	 * functions without conflict.
+	 *
+	 * @param bf
+	 */
+	void setFunction(bool_func bf) {
 		d_bool_func = bf;
-		d_btp_func  = 0;
-		d_proj_func = 0;
 	}
 
-	void setFunction(btp_func btp){
-		d_bool_func = 0;
+	void setFunction(btp_func btp) {
 		d_btp_func  = btp;
-		d_proj_func = 0;
 	}
 
-	void setFunction(proj_func pf){
-		d_bool_func = 0;
-		d_btp_func  = 0;
+	void setFunction(proj_func pf) {
 		d_proj_func = pf;
 	}
 
-	string getTypeString(){
-		if(d_bool_func)
-			return "boolean";
-		if(d_btp_func)
-			return "basetype";
-		if(d_proj_func)
-			return "projection";
-		return "null";
+	void setFunction(D4Function pf) {
+		d_d4_function = pf;
 	}
 
+	std::string getTypeString() {
+		if (d_bool_func) return "boolean";
+		if (d_btp_func) return "basetype";
+		if (d_proj_func) return "projection";
+		if (d_d4_function) return "D4Function";
+		return "null";
+	}
 
 	bool_func get_bool_func(){ return d_bool_func; }
 	btp_func  get_btp_func() { return d_btp_func;  }
 	proj_func get_proj_func(){ return d_proj_func; }
-
+	D4Function get_d4_function() { return d_d4_function; }
 };
 
 } /* namespace libdap */
-#endif /* ABSTRACTFUNCTION_H_ */
+#endif /* SERVER_FUNCTION_H_ */
diff --git a/ServerFunctionsList.cc b/ServerFunctionsList.cc
index eb117fa..acc91cc 100644
--- a/ServerFunctionsList.cc
+++ b/ServerFunctionsList.cc
@@ -79,9 +79,9 @@ void ServerFunctionsList::delete_instance() {
  */
 
 ServerFunctionsList::~ServerFunctionsList() {
-    std::multimap<string,libdap::ServerFunction *>::iterator fit;
+    SFLIter fit;
     for(fit=d_func_list.begin(); fit!=d_func_list.end() ; fit++){
-        libdap::ServerFunction *func = fit->second;
+        ServerFunction *func = fit->second;
         DBG(cerr << "ServerFunctionsList::~ServerFunctionsList() - Deleting ServerFunction " << func->getName() << " from ServerFunctionsList." << endl);
         delete func;
     }
@@ -109,75 +109,6 @@ void ServerFunctionsList::add_function(ServerFunction *func )
     d_func_list.insert(std::make_pair(func->getName(),func));
 }
 
-#if 0
-
-bool
-ServerFunctionsList::add_function( string name, btp_func func )
-{
-    if (d_btp_func_list[name] == 0) {
-        d_btp_func_list[name] = func;
-        return true;
-    }
-
-    return false;
-}
-
-
-bool
-ServerFunctionsList::add_function( string name, bool_func func )
-{
-    if (d_bool_func_list[name] == 0) {
-        d_bool_func_list[name] = func;
-        return true;
-    }
-
-    return false;
-}
-
-bool
-ServerFunctionsList::add_function( string name, proj_func func )
-{
-    if (d_proj_func_list[name] == 0) {
-        d_proj_func_list[name] = func;
-        return true;
-    }
-
-    return false;
-}
-#endif
-
-#if 0
-void ServerFunctionsList::store_functions(ConstraintEvaluator &ce)
-{
-    if (d_btp_func_list.size() > 0) {
-        map<string, btp_func>::iterator i = d_btp_func_list.begin();
-        map<string, btp_func>::iterator e = d_btp_func_list.end();
-        while (i != e) {
-            ce.add_function((*i).first, (*i).second);
-            ++i;
-        }
-    }
-
-    if (d_bool_func_list.size() > 0) {
-        map<string, bool_func>::iterator i = d_bool_func_list.begin();
-        map<string, bool_func>::iterator e = d_bool_func_list.end();
-        while (i != e) {
-            ce.add_function((*i).first, (*i).second);
-            ++i;
-        }
-    }
-
-    if (d_proj_func_list.size() > 0) {
-        map<string, proj_func>::iterator i = d_proj_func_list.begin();
-        map<string, proj_func>::iterator e = d_proj_func_list.end();
-        while (i != e) {
-            ce.add_function((*i).first, (*i).second);
-            ++i;
-        }
-    }
-}
-#endif
-
 /**
  * Returns the first boolean function in the list whose key value matches the passed string name.
  * When a match is found the function returns true and sets returned value parameter *f to
@@ -200,38 +131,21 @@ void ServerFunctionsList::store_functions(ConstraintEvaluator &ce)
  */
 bool ServerFunctionsList::find_function(const std::string &name, bool_func *f) const
 {
-#if 0
-    if (d_bool_func_list.empty())
-        return false;
-
-    map<string, bool_func>::const_iterator i = d_bool_func_list.begin();
-    while(i != d_bool_func_list.end()) {
-        if (name == (*i).first && (*f = (*i).second)) {
-            return true;
-        }
-        ++i;
-    }
-
-    return false;
-#endif
-
     if (d_func_list.empty())
         return false;
 
-    std::pair <std::multimap<std::string,libdap::ServerFunction *>::const_iterator, std::multimap<std::string,libdap::ServerFunction *>::const_iterator> ret;
+    std::pair <SFLCIter, SFLCIter> ret;
     ret = d_func_list.equal_range(name);
-    for (std::multimap<std::string,libdap::ServerFunction *>::const_iterator it=ret.first; it!=ret.second; ++it) {
+    for (SFLCIter it = ret.first; it != ret.second; ++it) {
         if (name == it->first && (*f = it->second->get_bool_func())){
             DBG(cerr << "ServerFunctionsList::find_function() - Found boolean function " << it->second->getName() << endl);
             return true;
         }
     }
-    return false;
 
+    return false;
 }
 
-
-
 /**
  * Returns the first BaseType function in the list whose key value matches the passed string name.
  * When a match is found the function returns true and sets returned value parameter *f to
@@ -254,29 +168,13 @@ bool ServerFunctionsList::find_function(const std::string &name, bool_func *f) c
  */
 bool ServerFunctionsList::find_function(const string &name, btp_func *f) const
 {
-
-#if 0
-    if (d_btp_func_list.empty())
-        return false;
-
-    map<string, btp_func>::const_iterator i = d_btp_func_list.begin();
-    while(i != d_btp_func_list.end()) {
-        if (name == (*i).first && (*f = (*i).second)) {
-            return true;
-        }
-        ++i;
-    }
-
-    return false;
-#endif
-
     if (d_func_list.empty())
         return false;
     DBG(cerr << "ServerFunctionsList::find_function() - Looking for ServerFunction '" << name << "'" << endl);
 
-    std::pair <std::multimap<string,libdap::ServerFunction *>::const_iterator, std::multimap<string,libdap::ServerFunction *>::const_iterator> ret;
+    std::pair <SFLCIter, SFLCIter> ret;
     ret = d_func_list.equal_range(name);
-    for (std::multimap<string,libdap::ServerFunction *>::const_iterator it=ret.first; it!=ret.second; ++it) {
+    for (SFLCIter it = ret.first; it != ret.second; ++it) {
         if (name == it->first && (*f = it->second->get_btp_func())){
             DBG(cerr << "ServerFunctionsList::find_function() - Found basetype function " << it->second->getName() << endl);
             return true;
@@ -284,9 +182,6 @@ bool ServerFunctionsList::find_function(const string &name, btp_func *f) const
     }
 
     return false;
-
-
-
 }
 
 /**
@@ -311,147 +206,73 @@ bool ServerFunctionsList::find_function(const string &name, btp_func *f) const
  */
 bool ServerFunctionsList::find_function(const string &name, proj_func *f) const
 {
-
-#if 0
-    if (d_proj_func_list.empty())
+    if (d_func_list.empty())
         return false;
 
-    map<string, proj_func>::const_iterator i = d_proj_func_list.begin();
-    while(i != d_proj_func_list.end()) {
-        if (name == (*i).first && (*f = (*i).second)) {
-            return true;
+    std::pair <SFLCIter, SFLCIter> ret;
+    ret = d_func_list.equal_range(name);
+    for (SFLCIter it = ret.first; it != ret.second; ++it) {
+        if (name == it->first && (*f = it->second->get_proj_func())){
+            DBG(cerr << "ServerFunctionsList::find_function() - Found projection function " << it->second->getName() << endl);
+           return true;
         }
-        ++i;
     }
 
     return false;
-#endif
+}
 
+/**
+ * Find a DAP4 function in the Server Functions List.
+ *
+ * @param name Look for this function name
+ * @param f Value-result parameter. NULL if the function is not found
+ * @return True if the function was found, otherwise false.
+ */
+bool ServerFunctionsList::find_function(const string &name, D4Function *f) const
+{
     if (d_func_list.empty())
         return false;
 
-    std::pair <std::multimap<string,libdap::ServerFunction *>::const_iterator, std::multimap<string,libdap::ServerFunction *>::const_iterator> ret;
+    std::pair <SFLCIter, SFLCIter> ret;
     ret = d_func_list.equal_range(name);
-    for (std::multimap<string,libdap::ServerFunction *>::const_iterator it=ret.first; it!=ret.second; ++it) {
-        if (name == it->first && (*f = it->second->get_proj_func())){
-            DBG(cerr << "ServerFunctionsList::find_function() - Found projection function " << it->second->getName() << endl);
-           return true;
+    for (SFLCIter it = ret.first; it != ret.second; ++it) {
+        if (name == it->first && (*f = it->second->get_d4_function())) {
+            return true;
         }
     }
-    return false;
 
+    return false;
 }
 
-
-
 /** @brief Returns an iterator pointing to the first key pair in the ServerFunctionList. */
-std::multimap<string,libdap::ServerFunction *>::iterator ServerFunctionsList::begin()
+ServerFunctionsList::SFLIter ServerFunctionsList::begin()
 {
     return d_func_list.begin();
 }
 
 /** @brief Returns an iterator pointing to the last key pair in the ServerFunctionList. */
-std::multimap<string,libdap::ServerFunction *>::iterator ServerFunctionsList::end()
+ServerFunctionsList::SFLIter ServerFunctionsList::end()
 {
     return d_func_list.end();
 }
 
-
 /**
  *
  *
  * @brief Returns the ServerFunction pointed to by the passed iterator.
  *
  */
-libdap::ServerFunction *ServerFunctionsList::getFunction(std::multimap<string,libdap::ServerFunction *>::iterator it)
+ServerFunction *ServerFunctionsList::getFunction(SFLIter it)
 {
     return (*it).second;
 }
 
-
-
-
-
-
-#if 0
-/** @brief dumps information about this object
- *
- * Displays the pointer value of this instance along with information about
- * this catalog directory.
- *
- * @param strm C++ i/o stream to dump the information to
- */
-void ServerFunctionsList::dump(ostream &strm) const
-{
-    strm << BESIndent::LMarg << "ServerFunctionsList::dump - (" << (void *) this << ")" << endl;
-    BESIndent::Indent();
-
-    if (d_btp_func_list.size() > 0) {
-        strm << BESIndent::LMarg << "registered btp functions:" << endl;
-        BESIndent::Indent();
-        map<string, btp_func>::const_iterator i = d_btp_func_list.begin();
-        map<string, btp_func>::const_iterator e = d_btp_func_list.end();
-        while (i != e) {
-            strm << (*i).first << endl;
-            ++i;
-        }
-        BESIndent::UnIndent();
-    }
-    else {
-        strm << BESIndent::LMarg << "registered btp functions: none" << endl;
-    }
-
-    if (d_bool_func_list.size() > 0) {
-        strm << BESIndent::LMarg << "registered bool functions:" << endl;
-        BESIndent::Indent();
-        map<string, bool_func>::const_iterator i = d_bool_func_list.begin();
-        map<string, bool_func>::const_iterator e = d_bool_func_list.end();
-        while (i != e) {
-            strm << (*i).first << endl;
-            ++i;
-        }
-        BESIndent::UnIndent();
-    }
-    else {
-        strm << BESIndent::LMarg << "registered bool functions: none" << endl;
-    }
-
-    if (d_proj_func_list.size() > 0) {
-        strm << BESIndent::LMarg << "registered projection functions:" << endl;
-        BESIndent::Indent();
-        map<string, proj_func>::const_iterator i = d_proj_func_list.begin();
-        map<string, proj_func>::const_iterator e = d_proj_func_list.end();
-        while (i != e) {
-            strm << (*i).first << endl;
-            ++i;
-        }
-        BESIndent::UnIndent();
-    }
-    else {
-        strm << BESIndent::LMarg << "registered projection functions: none" << endl;
-    }
-
-    BESIndent::UnIndent();
-}
-
-ServerFunctionsList *
-ServerFunctionsList::TheList()
-{
-    if (d_instance == 0) {
-        d_instance = new ServerFunctionsList;
-    }
-    return d_instance;
-}
-
-#endif
-
 void ServerFunctionsList::getFunctionNames(vector<string> *names){
-    std::multimap<string,libdap::ServerFunction *>::iterator fit;
-    for(fit=d_func_list.begin(); fit!=d_func_list.end() ; fit++){
+	SFLIter fit;
+    for(fit = d_func_list.begin(); fit != d_func_list.end(); fit++) {
         ServerFunction *func = fit->second;
         names->push_back(func->getName());
     }
 }
 
-
-}
+} // namespace libdap
diff --git a/ServerFunctionsList.h b/ServerFunctionsList.h
index 59c3551..b935d0a 100644
--- a/ServerFunctionsList.h
+++ b/ServerFunctionsList.h
@@ -32,50 +32,51 @@
 
 #include <map>
 #include <string>
-#include <expr.h>
 
-#include "ServerFunction.h"
+#include <expr.h>
+#include <D4Function.h>
 
+#include <ServerFunction.h>
 
 namespace libdap {
+
 class ServerFunctionsListUnitTest;
 class ConstraintEvaluator;
 
-//#include "BESObj.h"
-
 class ServerFunctionsList {
 private:
     static ServerFunctionsList * d_instance;
-    std::multimap<std::string, libdap::ServerFunction *> d_func_list;
+    std::multimap<std::string, ServerFunction *> d_func_list;
 
     static void initialize_instance();
     static void delete_instance();
 
     virtual ~ServerFunctionsList();
 
-    friend class libdap::ServerFunctionsListUnitTest;
+    friend class ServerFunctionsListUnitTest;
 
 protected:
     ServerFunctionsList() {}
 
 public:
-    static ServerFunctionsList * TheList();
-
+    // Added typedefs to reduce clutter jhrg 3/12/14
+    typedef std::multimap<std::string, ServerFunction *>::iterator SFLIter;
+    typedef std::multimap<std::string, ServerFunction *>::const_iterator SFLCIter;
 
-    virtual void add_function(libdap::ServerFunction *func);
-
-    virtual bool find_function(const std::string &name, libdap::bool_func *f) const;
-    virtual bool find_function(const std::string &name, libdap::btp_func  *f) const;
-    virtual bool find_function(const std::string &name, libdap::proj_func *f) const;
+    static ServerFunctionsList * TheList();
 
-    //virtual void dump(ostream &strm) const;
+    virtual void add_function(ServerFunction *func);
 
-    std::multimap<string,libdap::ServerFunction *>::iterator begin();
-    std::multimap<string,libdap::ServerFunction *>::iterator end();
-    ServerFunction *getFunction(std::multimap<string,libdap::ServerFunction *>::iterator it);
+    virtual bool find_function(const std::string &name, bool_func *f) const;
+    virtual bool find_function(const std::string &name, btp_func  *f) const;
+    virtual bool find_function(const std::string &name, proj_func *f) const;
+    virtual bool find_function(const std::string &name, D4Function *f) const;
 
-    virtual void getFunctionNames(vector<string> *names);
+    SFLIter begin();
+    SFLIter end();
+    ServerFunction *getFunction(SFLIter it);
 
+    virtual void getFunctionNames(std::vector<std::string> *names);
 };
 
 }
diff --git a/SignalHandler.cc b/SignalHandler.cc
index d894157..82fd446 100644
--- a/SignalHandler.cc
+++ b/SignalHandler.cc
@@ -153,19 +153,19 @@ 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:
+        case SIGHUP:
+        case SIGKILL:
+        case SIGUSR1:
+        case SIGUSR2:
+        case SIGPIPE:
+        case SIGALRM:
 #endif
-    case SIGINT:
-    case SIGTERM: break;
+        case SIGINT:
+        case SIGTERM: break;
 
-    default: throw InternalErr(__FILE__, __LINE__,
-                                   string("Call to register_handler with unsupported signal (")
-                                   + long_to_string(signum) + string(")."));
+        default: throw InternalErr(__FILE__, __LINE__,
+                string("Call to register_handler with unsupported signal (")
+                + long_to_string(signum) + string(")."));
     }
 
     // Save the old EventHandler
diff --git a/SignalHandler.h b/SignalHandler.h
index cd6ac7c..b3053b2 100644
--- a/SignalHandler.h
+++ b/SignalHandler.h
@@ -67,8 +67,8 @@ class SignalHandler
 {
 private:
     // Ensure we're a Singleton.
-    SignalHandler()
-    {}
+    SignalHandler() {}
+    SignalHandler(const SignalHandler &) {}
 
     // Singleton pointer.
     static SignalHandler *d_instance;
@@ -85,7 +85,7 @@ private:
     // 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
+    // Entry point adapter installed into sigaction(). This must be a 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);
@@ -104,8 +104,7 @@ public:
     static SignalHandler *instance();
 
     ///
-    virtual ~SignalHandler()
-    {}
+    virtual ~SignalHandler() {}
 
     EventHandler *register_handler(int signum, EventHandler *eh,
                                    bool override = false);
diff --git a/StdinResponse.h b/StdinResponse.h
index c5fc1ac..ec95c1a 100644
--- a/StdinResponse.h
+++ b/StdinResponse.h
@@ -28,15 +28,7 @@
 
 #include <cstdio>
 
-#ifndef response_h
 #include "Response.h"
-#endif
-
-#ifndef _debug_h
-#include "debug.h"
-#endif
-
-using namespace std;
 
 namespace libdap
 {
@@ -46,11 +38,14 @@ namespace libdap
     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. */
+    stream when it's done reading.
+
+    @note Modified 10/25/13 to accommodate C++ istreams. */
 class StdinResponse: public Response
 {
 private:
     FILE *d_stdin;
+    std::istream *d_cin;
 
 protected:
 
@@ -64,21 +59,22 @@ public:
         
         @param s Pointer to standard input.
         */
-    StdinResponse(FILE *s) : Response(0), d_stdin(s)
-    {}
+    StdinResponse(FILE *s) : Response(), d_stdin(s), d_cin(0) {}
+
+    /**
+     * @brief Build a instance using a C++ istream
+     * @param in A pointer to the input stream
+     */
+    StdinResponse(std::istream &in) : Response(), d_stdin(0), d_cin(&in) {}
 
     /** 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;
-    }
+    virtual ~StdinResponse() {}
+
+    virtual FILE *get_stream() const { return d_stdin; }
+    virtual void set_stream(FILE *s) { d_stdin = s; }
+
+    virtual std::istream *get_cpp_stream() const { return d_cin; }
+    virtual void set_cpp_stream(std::istream *in) { d_cin = in; }
 };
 
 } // namespace libdap
diff --git a/Str.cc b/Str.cc
index 04ab8b3..c1dd25a 100644
--- a/Str.cc
+++ b/Str.cc
@@ -52,10 +52,14 @@
 #include "Sequence.h"
 #include "Grid.h"
 
+#include "DDS.h"
 #include "Marshaller.h"
 #include "UnMarshaller.h"
 
-#include "DDS.h"
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
 #include "util.h"
 #include "parser.h"
 #include "Operators.h"
@@ -87,8 +91,7 @@ Str::Str(const string &n) : BaseType(n, dods_str_c), d_buf("")
     @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), d_buf("")
+Str::Str(const string &n, const string &d) : BaseType(n, d, dods_str_c), d_buf("")
 {}
 
 Str::Str(const Str &copy_from) : BaseType(copy_from)
@@ -116,21 +119,20 @@ Str::operator=(const Str &rhs)
     return *this;
 }
 
-unsigned int
-Str::length()
+int
+Str::length() const
 {
     return d_buf.length();
 }
 
 unsigned int
-Str::width(bool)
+Str::width(bool) const
 {
     return sizeof(string);
 }
 
 bool
-Str::serialize(ConstraintEvaluator &eval, DDS &dds,
-               Marshaller &m, bool ce_eval)
+Str::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval)
 {
 
     DBG(cerr << "Entering (" << this->name() << " [" << this << "])" << endl);
@@ -140,10 +142,8 @@ Str::serialize(ConstraintEvaluator &eval, DDS &dds,
     if (!read_p())
         read();
 
-#if EVAL
     if (ce_eval && !eval.eval_selection(dds, dataset()))
         return true;
-#endif
 
     dds.timeout_off();
 
@@ -164,6 +164,35 @@ Str::deserialize(UnMarshaller &um, DDS *, bool)
     return false;
 }
 
+void
+Str::compute_checksum(Crc32 &checksum)
+{
+	checksum.AddData(reinterpret_cast<const uint8_t*>(d_buf.data()), d_buf.length());
+}
+
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+Str::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+    m.put_str( d_buf ) ;
+}
+
+void
+Str::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+    um.get_str( d_buf ) ;
+}
+
 /** 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
diff --git a/Str.h b/Str.h
index ca1d93c..9e02f4a 100644
--- a/Str.h
+++ b/Str.h
@@ -61,7 +61,6 @@ const unsigned int max_str_len = DODS_USHRT_MAX - 1;
 
 class Str: public BaseType
 {
-
 protected:
     string d_buf;
 
@@ -78,16 +77,21 @@ public:
 
     virtual BaseType *ptr_duplicate();
 
-    virtual unsigned int width(bool constrained = false);
+    virtual unsigned int width(bool constrained = false) const;
 
     // 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 int length() const;
 
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true);
+    // DAP2
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval = true);
     virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
 
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
     virtual unsigned int val2buf(void *val, bool reuse = false);
     virtual unsigned int buf2val(void **val);
 
diff --git a/Structure.cc b/Structure.cc
index 026ff37..fe4823d 100644
--- a/Structure.cc
+++ b/Structure.cc
@@ -56,6 +56,9 @@
 #include "DDS.h"
 #include "ConstraintEvaluator.h"
 
+#include "D4Attributes.h"
+#include "D4Group.h"
+
 #include "XDRStreamMarshaller.h"
 #include "util.h"
 #include "debug.h"
@@ -122,15 +125,12 @@ Structure::Structure(const string &n, const string &d)
 /** The Structure copy constructor. */
 Structure::Structure(const Structure &rhs) : Constructor(rhs)
 {
-    m_duplicate(rhs);
+    DBG(cerr << "In Structure::copy_ctor for " << name() << endl);
+    //m_duplicate(rhs);
 }
 
 Structure::~Structure()
 {
-    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
-        BaseType *btp = *i ;
-        delete btp ;  btp = 0;
-    }
 }
 
 BaseType *
@@ -139,16 +139,44 @@ Structure::ptr_duplicate()
     return new Structure(*this);
 }
 
+/**
+ * Build a DAP4 Structure.
+ *
+ * This code must be subclassed for all but the most trivial cases.
+ *
+ * @param root
+ * @param container
+ * @return The new variable
+ */
+BaseType *
+Structure::transform_to_dap4(D4Group *root, Constructor *container)
+{
+	// For this class, ptr_duplicate() calls the const ctor which calls
+	// Constructor's const ctor which calls Constructor::m_duplicate().
+	// Here we replicate some of that functionality, but instead call
+	// transform_to_dap4() on the contained variables.
+
+	// Structure *dest = static_cast<Structure*>(ptr_duplicate());
+	Structure *dest = new Structure(name());
+
+	Constructor::transform_to_dap4(root, dest);
+	dest->set_parent(container);
+
+	return dest;
+}
+
 Structure &
 Structure::operator=(const Structure &rhs)
 {
+    DBG(cerr << "Entering Structure::operator=" << endl);
     if (this == &rhs)
         return *this;
 
     dynamic_cast<Constructor &>(*this) = rhs; // run Constructor=
 
-    m_duplicate(rhs);
+    //m_duplicate(rhs);
 
+    DBG(cerr << "Exiting Structure::operator=" << endl);
     return *this;
 }
 
@@ -527,8 +555,6 @@ Structure::m_exact_match(const string &name, btp_stack *s)
     return 0;
 }
 #endif
-// TODO Can these be removed and the versions in Constructor used instead?
-// Yes.
 #if 0
 void
 Structure::print_val(FILE *out, string space, bool print_decl_p)
diff --git a/Structure.h b/Structure.h
index ba67a90..30a024e 100644
--- a/Structure.h
+++ b/Structure.h
@@ -39,9 +39,6 @@
 #ifndef _structure_h
 #define _structure_h 1
 
-#ifndef __POWERPC__
-#endif
-
 #include <vector>
 
 #include "Constructor.h"
@@ -51,6 +48,7 @@ namespace libdap
 
 class DDS;
 class ConstraintEvaluator;
+class D4Group;
 
 /** This data type is used to hold a collection of related data types,
     in a manner roughly corresponding to a C structure.  The member
@@ -85,15 +83,7 @@ class ConstraintEvaluator;
 class Structure: public Constructor
 {
 private:
-#if 0
-    BaseType *m_leaf_match(const string &name, btp_stack *s = 0);
-    BaseType *m_exact_match(const string &name, btp_stack *s = 0);
-#endif
-
 protected:
-#if 0
-    void m_duplicate(const Structure &s);
-#endif
 
 public:
     Structure(const string &n);
@@ -105,59 +95,12 @@ public:
     Structure &operator=(const Structure &rhs);
     virtual BaseType *ptr_duplicate();
 
-#if 0
-    virtual int element_count(bool leaves = false);
-#endif
+    virtual BaseType *transform_to_dap4(D4Group *root, Constructor *container);
+
     virtual bool is_linear();
 
-#if 0
-    virtual void set_send_p(bool state);
-    virtual void set_read_p(bool state);
-#endif
-#if 0
-    virtual void set_in_selection(bool state);
-#endif
     virtual void set_leaf_sequence(int level = 1);
-#if 0
-    virtual unsigned int width(bool constrained = false);
-    virtual unsigned int width(bool constrained);
-#endif
-#if 0
-    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);
-#endif
-#if 0
-    // 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);
-#endif
-
-#if 0
-    virtual BaseType *var(const string &name, bool exact_match = true, btp_stack *s = 0);
-    virtual BaseType *var(const string &n, btp_stack &s);
-#endif
-#if 0
-    virtual void add_var(BaseType *bt, Part part = nil);
-    virtual void add_var_nocopy(BaseType *bt, Part part = nil);
-
-    virtual void del_var(const string &name);
-#endif
-#if 0
-    virtual bool read() ;
-#endif
-#if 0
-    virtual void print_val(FILE *out, string space = "",
-                           bool print_decl_p = true);
-    virtual void print_val(ostream &out, string space = "",
-                           bool print_decl_p = true);
-#endif
-#if 0
-    virtual bool check_semantics(string &msg, bool all = false);
-#endif
+
     virtual void dump(ostream &strm) const ;
 };
 
diff --git a/Type.h b/Type.h
new file mode 100644
index 0000000..5e71ad0
--- /dev/null
+++ b/Type.h
@@ -0,0 +1,127 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 TYPE_H_
+#define TYPE_H_
+
+namespace libdap {
+
+/** <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_structure_c,
+    dods_array_c,
+    dods_sequence_c,
+
+    dods_grid_c,
+
+    dods_char_c,
+    dods_int8_c,
+    dods_uint8_c,
+
+    dods_int64_c,
+    dods_uint64_c,
+    dods_enum_c,
+    dods_opaque_c,
+    dods_group_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_structure_c,
+    dods_array_c,
+    dods_sequence_c,
+
+    // Not used for DAP4
+    dods_grid_c,
+
+    // Added for DAP4
+    dods_char_c,	// a synonym for UInt8 (and Byte)
+    dods_int8_c,
+    dods_uint8_c,
+
+    dods_int64_c,
+    dods_uint64_c,
+    dods_enum_c,
+    dods_opaque_c,
+    dods_group_c
+};
+
+} // namespace libdap
+
+#endif /* TYPE_H_ */
diff --git a/UInt16.cc b/UInt16.cc
index e8938dc..c45dde4 100644
--- a/UInt16.cc
+++ b/UInt16.cc
@@ -51,10 +51,14 @@
 #include "Str.h"
 #include "Url.h"
 
+#include "DDS.h"
 #include "Marshaller.h"
 #include "UnMarshaller.h"
 
-#include "DDS.h"
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
 #include "util.h"
 #include "parser.h"
 #include "Operators.h"
@@ -71,8 +75,7 @@ namespace libdap {
 
     @param n A string containing the name of the variable to be created.
 */
-UInt16::UInt16(const string &n)
-        : BaseType(n, dods_uint16_c)
+UInt16::UInt16(const string &n) : BaseType(n, dods_uint16_c), d_buf(0)
 {}
 
 /** The UInt16 server-side constructor accepts the name of the variable to
@@ -82,8 +85,7 @@ UInt16::UInt16(const string &n)
     @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 string &n, const string &d) : BaseType(n, d, dods_uint16_c), d_buf(0)
 {}
 
 UInt16::UInt16(const UInt16 &copy_from) : BaseType(copy_from)
@@ -111,24 +113,21 @@ UInt16::operator=(const UInt16 &rhs)
 }
 
 unsigned int
-UInt16::width(bool)
+UInt16::width(bool) const
 {
     return sizeof(dods_uint16);
 }
 
 bool
-UInt16::serialize(ConstraintEvaluator &eval, DDS &dds,
-                  Marshaller &m, bool ce_eval)
+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();
 
@@ -145,6 +144,35 @@ UInt16::deserialize(UnMarshaller &um, DDS *, bool)
     return false;
 }
 
+void
+UInt16::compute_checksum(Crc32 &checksum)
+{
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
+
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+UInt16::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+    m.put_uint16( d_buf ) ;
+}
+
+void
+UInt16::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+    um.get_uint16( d_buf ) ;
+}
+
 unsigned int
 UInt16::val2buf(void *val, bool)
 {
diff --git a/UInt16.h b/UInt16.h
index 6587856..72c1a44 100644
--- a/UInt16.h
+++ b/UInt16.h
@@ -71,12 +71,17 @@ public:
 
     virtual BaseType *ptr_duplicate();
 
-    virtual unsigned int width(bool constrained = false);
+    virtual unsigned int width(bool constrained = false) const;
 
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true);
+    // DAP2
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,  Marshaller &m, bool ce_eval = true);
     virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
 
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
     virtual unsigned int val2buf(void *val, bool reuse = false);
     virtual unsigned int buf2val(void **val);
 
diff --git a/UInt32.cc b/UInt32.cc
index b202920..389dce7 100644
--- a/UInt32.cc
+++ b/UInt32.cc
@@ -51,10 +51,14 @@
 #include "Str.h"
 #include "Url.h"
 
+#include "DDS.h"
 #include "Marshaller.h"
 #include "UnMarshaller.h"
 
-#include "DDS.h"
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
 #include "util.h"
 #include "parser.h"
 #include "Operators.h"
@@ -72,8 +76,7 @@ namespace libdap {
     @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)
+UInt32::UInt32(const string &n) : BaseType(n, dods_uint32_c), d_buf(0)
 {}
 
 /** The UInt32 server-side constructor accepts the name of the variable and
@@ -83,8 +86,7 @@ UInt32::UInt32(const string &n)
     @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 string &n, const string &d) : BaseType(n, d, dods_uint32_c), d_buf(0)
 {}
 
 UInt32::UInt32(const UInt32 &copy_from) : BaseType(copy_from)
@@ -112,24 +114,21 @@ UInt32::operator=(const UInt32 &rhs)
 }
 
 unsigned int
-UInt32::width(bool)
+UInt32::width(bool) const
 {
     return sizeof(dods_uint32);
 }
 
 bool
-UInt32::serialize(ConstraintEvaluator &eval, DDS &dds,
-                  Marshaller &m, bool ce_eval)
+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();
 
@@ -146,6 +145,35 @@ UInt32::deserialize(UnMarshaller &um, DDS *, bool)
     return false;
 }
 
+void
+UInt32::compute_checksum(Crc32 &checksum)
+{
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
+
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+UInt32::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
+    if (!read_p())
+        read();          // read() throws Error
+
+    m.put_uint32( d_buf ) ;
+}
+
+void
+UInt32::deserialize(D4StreamUnMarshaller &um, DMR &)
+{
+    um.get_uint32( d_buf ) ;
+}
+
 unsigned int
 UInt32::val2buf(void *val, bool)
 {
diff --git a/UInt32.h b/UInt32.h
index 15d2222..2815f18 100644
--- a/UInt32.h
+++ b/UInt32.h
@@ -73,12 +73,17 @@ public:
 
     virtual BaseType *ptr_duplicate() ;
 
-    virtual unsigned int width(bool constrained = false);
+    virtual unsigned int width(bool constrained = false) const;
 
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true);
+    // DAP2
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,  Marshaller &m, bool ce_eval = true);
     virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
 
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
     virtual unsigned int val2buf(void *val, bool reuse = false);
     virtual unsigned int buf2val(void **val);
 
diff --git a/UInt64.cc b/UInt64.cc
index c622ad3..4282088 100644
--- a/UInt64.cc
+++ b/UInt64.cc
@@ -40,10 +40,10 @@
 #include "Str.h"
 #include "Url.h"
 
-#include "DAP4StreamMarshaller.h"
-#include "DAP4StreamUnMarshaller.h"
+#include "DMR.h"
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
 
-#include "DDS.h"
 #include "util.h"
 #include "parser.h"
 #include "Operators.h"
@@ -61,8 +61,7 @@ namespace libdap {
     @param n A string containing the name of the variable to be created.
     variable is created
 */
-UInt64::UInt64(const string &n)
-        : BaseType(n, dods_uint64_c)
+UInt64::UInt64(const string &n) : BaseType(n, dods_uint64_c), d_buf(0)
 {}
 
 /** The UInt64 server-side constructor accepts the name of the variable and
@@ -72,8 +71,7 @@ UInt64::UInt64(const string &n)
     @param d A string containing the name of the dataset from which this
     variable is created
 */
-UInt64::UInt64(const string &n, const string &d)
-        : BaseType(n, d, dods_uint64_c)
+UInt64::UInt64(const string &n, const string &d)  : BaseType(n, d, dods_uint64_c), d_buf(0)
 {}
 
 UInt64::UInt64(const UInt64 &copy_from) : BaseType(copy_from)
@@ -101,39 +99,38 @@ UInt64::operator=(const UInt64 &rhs)
 }
 
 unsigned int
-UInt64::width(bool)
+UInt64::width(bool) const
 {
     return sizeof(dods_uint64);
 }
 
-bool
-UInt64::serialize(ConstraintEvaluator &eval, DDS &dds,
-                  Marshaller &m, bool ce_eval)
+void
+UInt64::compute_checksum(Crc32 &checksum)
 {
-    dds.timeout_on();
+	checksum.AddData(reinterpret_cast<uint8_t*>(&d_buf), sizeof(d_buf));
+}
 
+/**
+ * @brief Serialize an Int8
+ * @param m
+ * @param dmr Unused
+ * @param eval Unused
+ * @param filter Unused
+ * @exception Error is thrown if the value needs to be read and that operation fails.
+ */
+void
+UInt64::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
+{
     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();
-
-    static_cast<DAP4StreamMarshaller*>(&m)->put_uint64( d_buf ) ;
+        read();          // read() throws Error
 
-    return true;
+    m.put_uint64( d_buf ) ;
 }
 
-bool
-UInt64::deserialize(UnMarshaller &um, DDS *, bool)
+void
+UInt64::deserialize(D4StreamUnMarshaller &um, DMR &)
 {
-    // TODO assert
-    static_cast<DAP4StreamUnMarshaller*>(&um)->get_uint64( d_buf ) ;
-
-    return false;
+    um.get_uint64( d_buf ) ;
 }
 
 dods_uint64
@@ -152,22 +149,14 @@ UInt64::set_value(dods_uint64 i)
 }
 
 void
-UInt64::print_val(FILE *out, string space, bool print_decl_p)
-{
-    ostringstream oss;
-    print_val(oss, space, print_decl_p);
-    fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
-}
-
-void
 UInt64::print_val(ostream &out, string space, bool print_decl_p)
 {
     if (print_decl_p) {
         print_decl(out, space, false);
-	out << " = " << (unsigned int)d_buf << ";\n" ;
+	out << " = " << d_buf << ";\n" ;
     }
     else
-	out << (unsigned int)d_buf ;
+	out << d_buf ;
 }
 
 bool
diff --git a/UInt64.h b/UInt64.h
index ca66344..4410d88 100644
--- a/UInt64.h
+++ b/UInt64.h
@@ -48,8 +48,12 @@ namespace libdap
 
 class UInt64: public BaseType
 {
-    virtual unsigned int val2buf(void *, bool)  { throw InternalErr(__FILE__, __LINE__, "Not implemented for UInt64"); }
+	virtual unsigned int val2buf(void *val, bool)  {
+    	set_value(*reinterpret_cast<dods_uint64*>(val));
+    	return sizeof(dods_uint64);
+    }
     virtual unsigned int buf2val(void **)  { throw InternalErr(__FILE__, __LINE__, "Not implemented for UInt64"); }
+    virtual void print_val(FILE *, string, bool) { throw InternalErr(__FILE__, __LINE__, "Not implemented for UInt64"); }
 
 protected:
     dods_uint64 d_buf;
@@ -66,19 +70,17 @@ public:
 
     virtual BaseType *ptr_duplicate() ;
 
-    virtual unsigned int width(bool constrained = false);
+    virtual unsigned int width(bool constrained = false) const;
 
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true);
-    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
 
     virtual dods_uint64 value() const;
     virtual bool set_value(dods_uint64 val);
 
-    virtual void print_val(FILE *out, string space = "",
-                           bool print_decl_p = true);
-    virtual void print_val(ostream &out, string space = "",
-                           bool print_decl_p = true);
+    virtual void print_val(ostream &out, string space = "",  bool print_decl_p = true);
 
     virtual bool ops(BaseType *b, int op);
 
diff --git a/Url.cc b/Url.cc
index e9ea1d3..d7337c2 100644
--- a/Url.cc
+++ b/Url.cc
@@ -33,6 +33,7 @@
 //
 // jhrg 9/7/94
 
+#include "config.h"
 
 #include "Url.h"
 
diff --git a/VCPP/sample/getdap.cc b/VCPP/sample/getdap.cc
index 75a6d58..1a72caf 100644
--- a/VCPP/sample/getdap.cc
+++ b/VCPP/sample/getdap.cc
@@ -36,7 +36,7 @@
 #define not_used
 
 static char rcsid[] not_used =
-    { "$Id: getdap.cc 27197 2013-10-01 21:29:54Z jimg $" };
+    { "$Id$" };
 
 #include <stdio.h>
 #ifdef WIN32
@@ -54,7 +54,7 @@ static char rcsid[] not_used =
 using std::cerr;
 using std::endl;
 
-const char *version = "$Revision: 27197 $";
+const char *version = "$Revision$";
 
 extern int dods_keep_temps;     // defined in HTTPResponse.h
 
diff --git a/Vector.cc b/Vector.cc
index f7f6ae7..467aec0 100644
--- a/Vector.cc
+++ b/Vector.cc
@@ -36,17 +36,29 @@
 #include "config.h"
 
 #include <cstring>
+#include <cassert>
 
 //#define DODS_DEBUG
 
 #include <sstream>
 #include <vector>
 #include <algorithm>
+#include <typeinfo>
+
+#include <stdint.h>
+
+#include "crc.h"
 
 #include "Vector.h"
 #include "Marshaller.h"
 #include "UnMarshaller.h"
 
+#include "D4StreamMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
+#include "D4Enum.h"
+
+#include "Type.h"
 #include "dods-datatypes.h"
 #include "escaping.h"
 #include "util.h"
@@ -58,37 +70,37 @@ using std::endl;
 
 namespace libdap {
 
-void Vector::_duplicate(const Vector & v)
+void Vector::m_duplicate(const Vector & v)
 {
     d_length = v.d_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.
+    if (v.d_proto) {
+        d_proto = v.d_proto->ptr_duplicate(); // use ptr_duplicate()
+        d_proto->set_parent(this); // ptr_duplicate does not set d_parent.
     }
     else {
-        _var = 0;
+        d_proto = 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
+    // d_compound_buf and d_buf (further down) hold the values of the Vector. The field
+    // d_compound_buf 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 d_buf
     // holds numeric values.
-    if (v._vec.empty()) {
-        _vec = v._vec;
+    if (v.d_compound_buf.empty()) {
+        d_compound_buf = v.d_compound_buf;
     }
     else {
         // Failure to set the size will make the [] operator barf on the LHS
         // of the assignment inside the loop.
-        _vec.resize(d_length);
+        d_compound_buf.resize(d_length);
         for (int i = 0; i < d_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();
+            // maintain the back pointer using the d_proto member. These
+            // instances are used to hold _values_ only while the d_proto
+            // field holds the type information for the elements.
+            d_compound_buf[i] = v.d_compound_buf[i]->ptr_duplicate();
         }
     }
 
@@ -96,40 +108,51 @@ void Vector::_duplicate(const Vector & v)
     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.
+    d_buf = 0; // init to null
+    if (v.d_buf) // only copy if data present
+        val2buf(v.d_buf); // store v's value in this's _BUF.
 
-    _capacity = v._capacity;
+    d_capacity = v.d_capacity;
 }
 
 /**
  * @return whether the type of this Vector is a cardinal type
- * (ie stored in _buf)
+ * (i.e., stored in d_buf)
  */
 bool Vector::m_is_cardinal_type() const
 {
-    // Not cardinal if no _var at all!
-    if (!_var) {
+	// TODO Is this true? It might not be
+    // Not cardinal if no d_proto at all!
+    if (!d_proto) {
         return false;
     }
 
-    switch (_var->type()) {
+    switch (d_proto->type()) {
         case dods_byte_c:
+        case dods_char_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_float64_c:
+        	// New cardinal types for DAP4
+        case dods_int8_c:
+        case dods_uint8_c:
+        case dods_int64_c:
+        case dods_uint64_c:
+
+        case dods_enum_c:
             return true;
             break;
-        }
 
             // These must be handled differently.
         case dods_str_c:
         case dods_url_c:
+        case dods_opaque_c:
+
         case dods_array_c:
+
         case dods_structure_c:
         case dods_sequence_c:
         case dods_grid_c:
@@ -137,9 +160,9 @@ bool Vector::m_is_cardinal_type() const
             break;
 
         default:
-            cerr << "Vector::var: Unrecognized type" << endl;
+            assert("Vector::var: Unrecognized type");
             return false;
-    } // switch
+    }
 }
 
 /**
@@ -157,7 +180,7 @@ bool Vector::m_is_cardinal_type() const
 unsigned int Vector::m_create_cardinal_data_buffer_for_type(unsigned int numEltsOfType)
 {
     // Make sure we HAVE a _var, or we cannot continue.
-    if (!_var) {
+    if (!d_proto) {
         throw InternalErr(__FILE__, __LINE__, "create_cardinal_data_buffer_for_type: Logic error: _var is null!");
     }
 
@@ -169,33 +192,27 @@ unsigned int Vector::m_create_cardinal_data_buffer_for_type(unsigned int numElts
     m_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 bytesPerElt = d_proto->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;
+    d_buf = new char[bytesNeeded];
+
+    d_capacity = numEltsOfType;
     return bytesNeeded;
 }
 
-/** Delete _buf and zero it and _capacity out */
+/** Delete d_buf and zero it and d_capacity out */
 void Vector::m_delete_cardinal_data_buffer()
 {
-    if (_buf) {
-        delete[] _buf;
-        _buf = 0;
-        _capacity = 0;
-    }
+	delete[] d_buf;
+	d_buf = 0;
+	d_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)
+void Vector::m_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!");
@@ -205,7 +222,7 @@ void Vector::set_cardinal_values_internal(const CardType* fromArray, int numElts
     }
     set_length(numElts);
     m_create_cardinal_data_buffer_for_type(numElts);
-    memcpy(_buf, fromArray, numElts * sizeof(CardType));
+    memcpy(d_buf, fromArray, numElts * sizeof(CardType));
     set_read_p(true);
 }
 
@@ -216,24 +233,23 @@ void Vector::set_cardinal_values_internal(const CardType* fromArray, int numElts
 
  @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 v A pointer to a prototype for elements.
  @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
+ method will be from the Array class.  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), d_length(-1), _var(0), _buf(0), _vec(0), _capacity(0)
+Vector::Vector(const string & n, BaseType * v, const Type & t, bool is_dap4 /* default:false */) :
+    BaseType(n, t, is_dap4), d_length(-1), d_proto(0), d_buf(0), d_compound_buf(0), d_capacity(0)
 {
     if (v)
         add_var(v);
 
     DBG2(cerr << "Entering Vector ctor for object: " << this << endl);
-    if (_var)
-        _var->set_parent(this);
+    if (d_proto)
+        d_proto->set_parent(this);
 }
 
 /** The Vector server-side constructor requires the name of the variable
@@ -246,24 +262,23 @@ Vector::Vector(const string & n, BaseType * v, const Type & t) :
  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 v A pointer to a prototype for elements.
  @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
+ method will be from the Array class.  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), d_length(-1), _var(0), _buf(0), _vec(0), _capacity(0)
+Vector::Vector(const string & n, const string &d, BaseType * v, const Type & t, bool is_dap4 /* default:false */) :
+    BaseType(n, d, t, is_dap4), d_length(-1), d_proto(0), d_buf(0), d_compound_buf(0), d_capacity(0)
 {
     if (v)
         add_var(v);
 
     DBG2(cerr << "Entering Vector ctor for object: " << this << endl);
-    if (_var)
-        _var->set_parent(this);
+    if (d_proto)
+        d_proto->set_parent(this);
 }
 
 /** The Vector copy constructor. */
@@ -273,15 +288,15 @@ Vector::Vector(const Vector & rhs) :
     DBG2(cerr << "Entering Vector const ctor for object: " << this <<
             endl); DBG2(cerr << "RHS: " << &rhs << endl);
 
-    _duplicate(rhs);
+    m_duplicate(rhs);
 }
 
 Vector::~Vector()
 {
     DBG2(cerr << "Entering ~Vector (" << this << ")" << endl);
 
-    delete _var;
-    _var = 0;
+    delete d_proto;
+    d_proto = 0;
 
     // Clears all buffers
     clear_local_data();
@@ -296,27 +311,18 @@ Vector & Vector::operator=(const Vector & rhs)
 
     dynamic_cast<BaseType &> (*this) = rhs;
 
-    _duplicate(rhs);
+    m_duplicate(rhs);
 
     return *this;
 }
 
-/**
- * The Vector (and Array) classes are specific to DAP2. They do not support
- * the semantics of DAP4 which allows varying dimensions.
- */
-bool Vector::is_dap2_only_type()
-{
-    return true;
-}
-
 void Vector::set_name(const std::string& name)
 {
     BaseType::set_name(name);
-    // We need to set the template variable name as well since
+    // We need to set the prototype name as well since
     // this is what gets output in the dds!  Otherwise, there's a mismatch.
-    if (_var) {
-        _var->set_name(name);
+    if (d_proto) {
+        d_proto->set_name(name);
     }
 }
 
@@ -325,8 +331,9 @@ int Vector::element_count(bool leaves)
     if (!leaves)
         return 1;
     else
+    	return d_proto->element_count(leaves);
         // var() only works for simple types!
-        return var(0)->element_count(leaves);
+        // jhrg 8/19/13 return var(0)->element_count(leaves);
 }
 
 // These mfuncs set the _send_p and _read_p fields of BaseType. They differ
@@ -342,7 +349,7 @@ int Vector::element_count(bool leaves)
  @brief Indicates that the data is ready to send. */
 void Vector::set_send_p(bool state)
 {
-    _var->set_send_p(state);
+    d_proto->set_send_p(state);
     BaseType::set_send_p(state);
 }
 
@@ -354,8 +361,8 @@ void Vector::set_send_p(bool state)
  @brief Indicates that the data is ready to send.  */
 void Vector::set_read_p(bool state)
 {
-    if (_var) {
-        _var->set_read_p(state);
+    if (d_proto) {
+        d_proto->set_read_p(state);
     }
     BaseType::set_read_p(state);
 }
@@ -380,26 +387,26 @@ void Vector::set_read_p(bool state)
 BaseType *Vector::var(const string &n, bool exact, btp_stack *s)
 {
     string name = www2id(n);
-    DBG(cerr << "Vector::var: Looking for " << n << endl);
+    DBG2(cerr << "Vector::var: Looking for " << name << endl);
 
     // If this is a Vector of constructor types, look for 'name' recursively.
     // 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 (d_proto->is_constructor_type()) {
+        if (name == "" || d_proto->name() == name) {
             if (s)
                 s->push(this);
-            return _var;
+            return d_proto;
         }
         else {
-            BaseType * result = _var->var(name, exact, s);
+            BaseType * result = d_proto->var(name, exact, s);
             if (result && s)
                 s->push(this);
             return result;
         }
     }
     else {
-        return _var;
+        return d_proto;
     }
 }
 
@@ -417,23 +424,14 @@ BaseType *Vector::var(const string & n, btp_stack & s)
 {
     string name = www2id(n);
 
-    if (_var->is_constructor_type())
-        return _var->var(name, s);
+    if (d_proto->is_constructor_type())
+        return d_proto->var(name, s);
     else {
         s.push((BaseType *) this);
-        return _var;
+        return d_proto;
     }
 }
 
-// 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.
@@ -448,70 +446,66 @@ BaseType *Vector::var(const string & n, btp_stack & s)
 BaseType *Vector::var(unsigned int i)
 {
 
-    switch (_var->type()) {
+    switch (d_proto->type()) {
         case dods_byte_c:
+        case dods_char_c:
+        case dods_int8_c:
+        case dods_uint8_c:
         case dods_int16_c:
         case dods_uint16_c:
         case dods_int32_c:
         case dods_uint32_c:
+        case dods_int64_c:
+        case dods_uint64_c:
+
+        case dods_enum_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;
+        case dods_float64_c:
+            // Transfer the ith value to the BaseType *d_proto
+            d_proto->val2buf(d_buf + (i * d_proto->width()));
+            return d_proto;
             break;
-        }
 
         case dods_str_c:
         case dods_url_c:
-            _var->val2buf(&d_str[i]);
-            return _var;
+            d_proto->val2buf(&d_str[i]);
+            return d_proto;
             break;
 
+        case dods_opaque_c:
         case dods_array_c:
         case dods_structure_c:
         case dods_sequence_c:
         case dods_grid_c:
-            return _vec[i];
+            return d_compound_buf[i];
             break;
 
         default:
             throw Error ("Vector::var: Unrecognized type");
-            //cerr << "Vector::var: Unrecognized type" << endl;
             break;
     }
 
     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
+/** Returns the number of bytes needed to hold the entire
+ array.  This is equal to \c length() (the number of elements in
+ in the array) times the width of each
  element.
 
  @brief Returns the width of the data, in bytes. */
-unsigned int Vector::width(bool constrained)
+unsigned int Vector::width(bool constrained) const
 {
     // Jose Garcia
-    if (!_var) {
+	// TODO Use assert.
+	if (!d_proto) {
         throw InternalErr(__FILE__, __LINE__, "Cannot get width since *this* object is not holding data.");
     }
 
-    return length() * _var->width(constrained);
+    return length() * d_proto->width(constrained);
 }
 
-// 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.
 
@@ -521,10 +515,6 @@ int Vector::length() const
     return d_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)
@@ -532,18 +522,22 @@ void Vector::set_length(int l)
     d_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. */
+ length is shorter, the tail values are discarded.
+
+ @note This method is applicable to the compound types only.
+ */
 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.
+    // I added this check, which alters the behavior of the method. jhrg 8/14/13
+    if (m_is_cardinal_type())
+        throw InternalErr(__FILE__, __LINE__, "Vector::vec_resize() is applicable to compound types only");
+
+    d_compound_buf.resize((l > 0) ? l : 0, 0); // Fill with NULLs
+    d_capacity = l; // capacity in terms of number of elements.
 }
 
 /** @brief read data into a variable for later use
@@ -558,7 +552,8 @@ void Vector::vec_resize(int l)
  This method is intended to be used by objects which transform DAP objects
  like the DataDDS into an ASCII CSV representation.
 
- the data source.
+ @note A DAP2-only method
+
  @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)
@@ -570,7 +565,7 @@ void Vector::intern_data(ConstraintEvaluator &eval, DDS &dds)
     // length() is not capacity; it must be set explicitly in read().
     int num = length();
 
-    switch (_var->type()) {
+    switch (d_proto->type()) {
         case dods_byte_c:
         case dods_int16_c:
         case dods_uint16_c:
@@ -578,19 +573,18 @@ void Vector::intern_data(ConstraintEvaluator &eval, DDS &dds)
         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.
+            // For these cases, read() puts the data into d_buf,
+        	// which is what we need.
             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.
+            // For these cases, read() will put the data into d_str[],
+        	// which is also what we need.
             break;
 
         case dods_array_c:
-            // I think this is an error since there can never be an Array of
-            // Array.
+            // This is an error since there can never be an Array of Array.
             throw InternalErr(__FILE__, __LINE__, "Array of Array not supported.");
             break;
 
@@ -599,12 +593,12 @@ void Vector::intern_data(ConstraintEvaluator &eval, DDS &dds)
         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)
+            // elements in the 'd_compound_buf[]' array of BaseType object pointers.
+            if (d_compound_buf.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);
+                d_compound_buf[i]->intern_data(eval, dds);
 
             break;
 
@@ -629,24 +623,25 @@ bool Vector::serialize(ConstraintEvaluator & eval, DDS & dds, Marshaller &m, boo
 {
     int i = 0;// TODO move closer to use
 
+    // TODO Time out here? or in ResponseBuilder?
     dds.timeout_on();
 
     if (!read_p())
         read(); // read() throws Error and InternalErr
 
-#if EVAL
+//#if EVAL
     if (ce_eval && !eval.eval_selection(dds, dataset()))
         return true;
-#endif
+//#endif
 
     dds.timeout_off();
 
     // length() is not capacity; it must be set explicitly in read().
     int num = length();
 
-    switch (_var->type()) {
+    switch (d_proto->type()) {
         case dods_byte_c:
-            m.put_vector(_buf, num, *this);
+            m.put_vector(d_buf, num, *this);
             break;
         case dods_int16_c:
         case dods_uint16_c:
@@ -654,7 +649,7 @@ bool Vector::serialize(ConstraintEvaluator & eval, DDS & dds, Marshaller &m, boo
         case dods_uint32_c:
         case dods_float32_c:
         case dods_float64_c:
-            m.put_vector(_buf, num, _var->width(), *this);
+            m.put_vector(d_buf, num, d_proto->width(), *this);
             break;
 
         case dods_str_c:
@@ -674,14 +669,14 @@ bool Vector::serialize(ConstraintEvaluator & eval, DDS & dds, Marshaller &m, boo
         case dods_sequence_c:
         case dods_grid_c:
             //Jose Garcia
-            // Not setting the capacity of _vec is an internal error.
-            if (_vec.capacity() == 0)
+            // Not setting the capacity of d_compound_buf is an internal error.
+            if (d_compound_buf.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);
+                d_compound_buf[i]->serialize(eval, dds, m, false);
 
             break;
 
@@ -715,7 +710,7 @@ bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
     unsigned int num;
     unsigned i = 0;
 
-    switch (_var->type()) {
+    switch (d_proto->type()) {
         case dods_byte_c:
         case dods_int16_c:
         case dods_uint16_c:
@@ -723,10 +718,6 @@ bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
         case dods_uint32_c:
         case dods_float32_c:
         case dods_float64_c:
-            if (_buf && !reuse) {
-                m_delete_cardinal_data_buffer();
-            }
-
             um.get_int((int &) num);
 
             DBG(cerr << "Vector::deserialize: num = " << num << endl);
@@ -738,18 +729,19 @@ bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
             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()
+            if (!d_buf || !reuse) {
+                // Make d_buf be large enough for length() elements of _var->type()
+            	// m_create...() deletes the old buffer.
                 m_create_cardinal_data_buffer_for_type(length());
                 DBG(cerr << "Vector::deserialize: allocating "
                         << width() << " bytes for an array of "
-                        << length() << " " << _var->type_name() << endl);
+                        << length() << " " << d_proto->type_name() << endl);
             }
 
-            if (_var->type() == dods_byte_c)
-                um.get_vector((char **) &_buf, num, *this);
+            if (d_proto->type() == dods_byte_c)
+                um.get_vector((char **) &d_buf, num, *this);
             else
-                um.get_vector((char **) &_buf, num, _var->width(), *this);
+                um.get_vector((char **) &d_buf, num, d_proto->width(), *this);
 
             DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
 
@@ -766,7 +758,7 @@ bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
                 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.
+            d_capacity = num; // capacity is number of strings we can fit.
 
             for (i = 0; i < num; ++i) {
                 string str;
@@ -792,8 +784,8 @@ bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
             vec_resize(num);
 
             for (i = 0; i < num; ++i) {
-                _vec[i] = _var->ptr_duplicate();
-                _vec[i]->deserialize(um, dds);
+                d_compound_buf[i] = d_proto->ptr_duplicate();
+                d_compound_buf[i]->deserialize(um, dds);
             }
 
             break;
@@ -806,6 +798,249 @@ bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
     return false;
 }
 
+void Vector::compute_checksum(Crc32 &checksum)
+{
+    switch (d_proto->type()) {
+        case dods_byte_c:
+        case dods_char_c:
+        case dods_int8_c:
+        case dods_uint8_c:
+
+        case dods_int16_c:
+        case dods_uint16_c:
+
+        case dods_int32_c:
+        case dods_uint32_c:
+        case dods_float32_c:
+
+        case dods_int64_c:
+        case dods_uint64_c:
+        case dods_float64_c:
+
+        case dods_enum_c:
+        	checksum.AddData(reinterpret_cast<uint8_t*>(d_buf), length() * d_proto->width());
+        	break;
+
+        case dods_str_c:
+        case dods_url_c:
+        	for (int64_t i = 0, e = length(); i < e; ++i)
+        		checksum.AddData(reinterpret_cast<const uint8_t*>(d_str[i].data()), d_str[i].length());
+            break;
+
+        case dods_opaque_c:
+        case dods_structure_c:
+        case dods_sequence_c:
+        	d_proto->compute_checksum(checksum);
+        	break;
+
+        case dods_array_c:	// No array of array
+        case dods_grid_c:	// No grids in DAP4
+        default:
+            throw InternalErr(__FILE__, __LINE__, "Unknown or unsupported datatype (" + d_proto->type_name() + ").");
+            break;
+    }
+}
+
+void Vector::intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator &eval*/)
+{
+    if (!read_p())
+        read(); // read() throws Error and InternalErr
+
+    switch (d_proto->type()) {
+        case dods_byte_c:
+        case dods_char_c:
+        case dods_int8_c:
+        case dods_uint8_c:
+        case dods_int16_c:
+        case dods_uint16_c:
+        case dods_int32_c:
+        case dods_uint32_c:
+        case dods_int64_c:
+        case dods_uint64_c:
+
+        case dods_enum_c:
+
+        case dods_float32_c:
+        case dods_float64_c:
+
+        case dods_str_c:
+        case dods_url_c:
+        	compute_checksum(checksum);
+            break;
+
+        case dods_opaque_c:
+        case dods_structure_c:
+        case dods_sequence_c:
+            assert(d_compound_buf.capacity() != 0);
+
+            for (int i = 0, e = length(); i < e; ++i)
+                d_compound_buf[i]->intern_data(checksum/*, dmr, eval*/);
+            break;
+
+        case dods_array_c:
+        case dods_grid_c:
+        default:
+        	throw InternalErr(__FILE__, __LINE__, "Unknown or unsupported datatype (" + d_proto->type_name() + ").");
+            break;
+    }
+}
+
+void
+Vector::serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter /*= false*/)
+{
+    if (!read_p())
+        read(); // read() throws Error and InternalErr
+#if 0
+    if (filter && !eval.eval_selection(dmr, dataset()))
+        return true;
+#endif
+    int64_t num = length();	// The constrained length in elements
+
+    switch (d_proto->type()) {
+        case dods_byte_c:
+        case dods_char_c:
+        case dods_int8_c:
+        case dods_uint8_c:
+            m.put_vector(d_buf, num);
+            break;
+
+        case dods_int16_c:
+        case dods_uint16_c:
+        case dods_int32_c:
+        case dods_uint32_c:
+        case dods_int64_c:
+        case dods_uint64_c:
+        	m.put_vector(d_buf, num, d_proto->width());
+        	break;
+
+        case dods_enum_c:
+        	if (d_proto->width() == 1)
+        		m.put_vector(d_buf, num);
+        	else
+        		m.put_vector(d_buf, num, d_proto->width());
+        	break;
+
+        case dods_float32_c:
+            m.put_vector_float32(d_buf, num);
+            break;
+
+        case dods_float64_c:
+            m.put_vector_float64(d_buf, num);
+            break;
+
+        case dods_str_c:
+        case dods_url_c:
+            assert((int64_t)d_str.capacity() >= num);
+
+            for (int64_t i = 0; i < num; ++i)
+                m.put_str(d_str[i]);
+
+            break;
+
+        case dods_array_c:
+        	throw InternalErr(__FILE__, __LINE__, "Array of Array not allowed.");
+
+        case dods_opaque_c:
+        case dods_structure_c:
+        case dods_sequence_c:
+            assert(d_compound_buf.capacity() >= 0);
+
+            for (int64_t i = 0; i < num; ++i)
+                d_compound_buf[i]->serialize(m, dmr, /*eval,*/ filter);
+
+            break;
+
+        case dods_grid_c:
+        	throw InternalErr(__FILE__, __LINE__, "Grid is not part of DAP4.");
+
+        default:
+            throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
+            break;
+    }
+}
+
+void
+Vector::deserialize(D4StreamUnMarshaller &um, DMR &dmr)
+{
+    if (m_is_cardinal_type()) {
+        if (d_buf)
+            m_delete_cardinal_data_buffer();
+        if (!d_buf)
+            m_create_cardinal_data_buffer_for_type(length());
+    }
+
+    DBG(cerr << "Vector::deserialize, " << name() << ", length(): " << length() << endl);
+
+    switch (d_proto->type()) {
+        case dods_byte_c:
+        case dods_char_c:
+        case dods_int8_c:
+        case dods_uint8_c:
+        	um.get_vector((char *)d_buf, length());
+        	break;
+
+        case dods_int16_c:
+        case dods_uint16_c:
+        case dods_int32_c:
+        case dods_uint32_c:
+        case dods_int64_c:
+        case dods_uint64_c:
+        	um.get_vector((char *)d_buf, length(), d_proto->width());
+        	break;
+
+        case dods_enum_c:
+        	if (d_proto->width() == 1)
+        		um.get_vector((char *)d_buf, length());
+        	else
+        		um.get_vector((char *)d_buf, length(), d_proto->width());
+        	break;
+
+        case dods_float32_c:
+            um.get_vector_float32((char *)d_buf, length());
+            break;
+
+        case dods_float64_c:
+        	um.get_vector_float64((char *)d_buf, length());
+            break;
+
+        case dods_str_c:
+        case dods_url_c: {
+        	int64_t len = length();
+            d_str.resize((len > 0) ? len : 0); // Fill with NULLs
+            d_capacity = len; // capacity is number of strings we can fit.
+
+            for (int64_t i = 0; i < len; ++i) {
+                um.get_str(d_str[i]);
+            }
+
+            break;
+        }
+
+        case dods_array_c:
+        	throw InternalErr(__FILE__, __LINE__, "Array of Array not allowed.");
+
+        case dods_opaque_c:
+        case dods_structure_c:
+        case dods_sequence_c: {
+            vec_resize(length());
+
+            for (int64_t i = 0, end = length(); i < end; ++i) {
+                d_compound_buf[i] = d_proto->ptr_duplicate();
+                d_compound_buf[i]->deserialize(um, dmr);
+            }
+
+            break;
+        }
+
+        case dods_grid_c:
+        	throw InternalErr(__FILE__, __LINE__, "Grid is not part of DAP4.");
+
+        default:
+            throw InternalErr(__FILE__, __LINE__, "Unknown type.");
+            break;
+    }
+}
+
 /** 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
@@ -847,39 +1082,45 @@ unsigned int Vector::val2buf(void *val, bool reuse)
     if (!val)
         throw InternalErr(__FILE__, __LINE__, "The incoming pointer does not contain any data.");
 
-    switch (_var->type()) {
+    switch (d_proto->type()) {
         case dods_byte_c:
+        case dods_char_c:
+        case dods_int8_c:
+        case dods_uint8_c:
         case dods_int16_c:
         case dods_uint16_c:
         case dods_int32_c:
         case dods_uint32_c:
+        case dods_int64_c:
+        case dods_uint64_c:
+
+        case dods_enum_c:
+
         case dods_float32_c:
-        case dods_float64_c: {
-            // width(true) returns the size given the constraint
-            unsigned int array_wid = width(true);
-            if (_buf && !reuse) {
+        case dods_float64_c:
+#if 0
+        	if (d_buf && !reuse)
                 m_delete_cardinal_data_buffer();
-            }
-
-            if (!_buf) { // First time or no reuse (free'd above)
+#endif
+            // First time or no reuse (free'd above)
+            if (!d_buf || !reuse)
                 m_create_cardinal_data_buffer_for_type(length());
-            }
 
-            memcpy(_buf, val, array_wid);
+            // width(true) returns the size in bytes given the constraint
+            memcpy(d_buf, val, width(true));
             break;
-        }
 
         case dods_str_c:
-        case dods_url_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.
+            // Note: d_length is the number of elements in the Vector
             d_str.resize(d_length);
-            _capacity = d_length;
+            d_capacity = d_length;
             for (int i = 0; i < d_length; ++i)
                 d_str[i] = *(static_cast<string *> (val) + i);
 
             break;
-        }
 
         default:
             throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
@@ -927,57 +1168,65 @@ unsigned int Vector::buf2val(void **val)
         throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
 
     unsigned int wid = static_cast<unsigned int> (width(true /* constrained */));
+
     // 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()) {
+    switch (d_proto->type()) {
         case dods_byte_c:
+        case dods_char_c:
+        case dods_int8_c:
+        case dods_uint8_c:
         case dods_int16_c:
         case dods_uint16_c:
         case dods_int32_c:
         case dods_uint32_c:
+        case dods_int64_c:
+        case dods_uint64_c:
+
+        case dods_enum_c:
+
         case dods_float32_c:
         case dods_float64_c:
-            if (!*val) {
+            if (!d_buf)
+                throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: Logic error: called when cardinal type data buffer was empty!");
+            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);
 
+            memcpy(*val, d_buf, wid);
+            return wid;
             break;
 
         case dods_str_c:
         case dods_url_c: {
+        	if (d_str.empty())
+        		throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: Logic error: called when string data buffer was empty!");
             if (!*val)
                 *val = new string[d_length];
 
             for (int i = 0; i < d_length; ++i)
                 *(static_cast<string *> (*val) + i) = d_str[i];
 
+            return width();
             break;
         }
 
         default:
             throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
-            return 0;
     }
 
-    return wid;
+    //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.
+ Use this function only with Vectors containing compound
+ types.  See \c buf2val() or the \c set_value() methods to access
+ members of Vector containing simple types.
 
  @note This method copies \e val; the caller is responsible for deleting
  instance passed as the actual parameter.
@@ -993,6 +1242,17 @@ unsigned int Vector::buf2val(void **val)
  @see Vector::buf2val */
 void Vector::set_vec(unsigned int i, BaseType * val)
 {
+	Vector::set_vec_nocopy(i, val->ptr_duplicate());
+}
+
+/** @brief Sets element <i>i</i> to value <i>val</i>.
+
+ @note This method does not copy \e val; this class will free the instance
+ when the variable is deleted or when clear_local_data() is called.
+
+ @see Vector::set_vec() */
+void Vector::set_vec_nocopy(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
@@ -1001,19 +1261,19 @@ void Vector::set_vec(unsigned int i, BaseType * val)
         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())
+    if (val->type() != d_proto->type())
         throw InternalErr(__FILE__, __LINE__, "invalid data: type of incoming object does not match *this* vector type.");
 
-    if (i >= _vec.capacity())
+    if (i >= d_compound_buf.capacity())
         vec_resize(i + 10);
 
-    _vec[i] = val->ptr_duplicate();
+    d_compound_buf[i] = val;
 }
 
 /**
  * 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.
+ * Essentially clears the _buf, d_str, and d_compound_buf 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!
@@ -1021,34 +1281,34 @@ void Vector::set_vec(unsigned int i, BaseType * val)
  */
 void Vector::clear_local_data()
 {
-    if (_buf) {
-        delete[] _buf;
-        _buf = 0;
+    if (d_buf) {
+        delete[] d_buf;
+        d_buf = 0;
     }
 
-    for (unsigned int i = 0; i < _vec.size(); ++i) {
-        delete _vec[i];
-        _vec[i] = 0;
+    for (unsigned int i = 0; i < d_compound_buf.size(); ++i) {
+        delete d_compound_buf[i];
+        d_compound_buf[i] = 0;
     }
 
     // Force memory to be reclaimed.
-    _vec.resize(0);
+    d_compound_buf.resize(0);
     d_str.resize(0);
 
-    _capacity = 0;
+    d_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).
+ * 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;
+    return d_capacity;
 }
 
 /**
@@ -1062,44 +1322,52 @@ unsigned int Vector::get_value_capacity() const
  */
 void Vector::reserve_value_capacity(unsigned int numElements)
 {
-    if (!_var) {
+    if (!d_proto) {
         throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Logic error: _var is null!");
     }
-    switch (_var->type()) {
+    switch (d_proto->type()) {
         case dods_byte_c:
+        case dods_char_c:
+        case dods_int8_c:
+        case dods_uint8_c:
         case dods_int16_c:
         case dods_uint16_c:
         case dods_int32_c:
         case dods_uint32_c:
+        case dods_int64_c:
+        case dods_uint64_c:
+
+        case dods_enum_c:
+
         case dods_float32_c:
-        case dods_float64_c: {
+        case dods_float64_c:
             // Make _buf be the right size and set _capacity
             m_create_cardinal_data_buffer_for_type(numElements);
-        }
             break;
 
         case dods_str_c:
-        case dods_url_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;
-        }
+            d_capacity = numElements;
             break;
 
         case dods_array_c:
+            throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Arrays not supported!");
+            break;
+
+        case dods_opaque_c:
         case dods_structure_c:
         case dods_sequence_c:
-        case dods_grid_c: {
+        case dods_grid_c:
             // not clear anyone will go this path, but best to be complete.
-            _vec.reserve(numElements);
-            _capacity = numElements;
-        }
+            d_compound_buf.reserve(numElements);
+            d_capacity = numElements;
             break;
 
-        default: {
+        default:
             throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Unknown type!");
-        }
             break;
 
     } // switch
@@ -1145,100 +1413,241 @@ void Vector::reserve_value_capacity()
  * @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);
+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() && d_proto && (rowMajorData.var()->type() == d_proto->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 amount 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 (d_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 (d_proto->type()) {
+		case dods_int8_c:
+		case dods_uint8_c:
+		case dods_byte_c:
+        case dods_char_c:
+		case dods_int16_c:
+		case dods_uint16_c:
+		case dods_int32_c:
+		case dods_uint32_c:
+		case dods_int64_c:
+		case dods_uint64_c:
+
+		case dods_enum_c:
+
+		case dods_float32_c:
+		case dods_float64_c: {
+			if (!d_buf) {
+				throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: this->_buf was unexpectedly null!");
+			}
+			if (!rowMajorData.d_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 = d_proto->width();
+			char* pFromBuf = rowMajorData.d_buf;
+			int numBytesToCopy = rowMajorData.width(true);
+			char* pIntoBuf = d_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_opaque_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: array, opaque, structure, sequence or grid.");
+			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();
+}
 
-    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!");
+/**
+ * Does the C++ type correspond to the DAP Type enum value? This works only for
+ * numeric cardinal types. For Enums, pass the value of element_type(); for all
+ * others use type().
+ * @param t
+ * @param dt
+ * @return True if the types match, false otherwise
+ */
+template <typename T>
+static bool types_match(Type t, T *cpp_var)
+{
+    switch (t) {
+    case dods_byte_c:
+    case dods_char_c:
+    case dods_uint8_c:
+        return typeid(cpp_var) == typeid(dods_byte*);
+
+    case dods_int8_c:
+        return typeid(cpp_var) == typeid(dods_int8*);
+    case dods_int16_c:
+        return typeid(cpp_var) == typeid(dods_int16*);
+    case dods_uint16_c:
+        return typeid(cpp_var) == typeid(dods_uint16*);
+    case dods_int32_c:
+        return typeid(cpp_var) == typeid(dods_int32*);
+    case dods_uint32_c:
+        return typeid(cpp_var) == typeid(dods_uint32*);
+    case dods_int64_c:
+        return typeid(cpp_var) == typeid(dods_int64*);
+    case dods_uint64_c:
+        return typeid(cpp_var) == typeid(dods_uint64*);
+
+    case dods_float32_c:
+        return typeid(cpp_var) == typeid(dods_float32*);
+    case dods_float64_c:
+        return typeid(cpp_var) == typeid(dods_float64*);
+
+    case dods_null_c:
+    case dods_enum_c:
+    case dods_str_c:
+    case dods_url_c:
+    case dods_opaque_c:
+    case dods_array_c:
+    case dods_structure_c:
+    case dods_sequence_c:
+    case dods_group_c:
+    default:
+        return false;
     }
+}
 
-    // 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!");
-    }
+//@{
+/** @brief set the value of a byte array */
 
-    // 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!");
-    }
+template <typename T>
+bool Vector::set_value(T *v, int sz)
+{
+    if (!v || !types_match(d_proto->type() == dods_enum_c ? static_cast<D4Enum*>(d_proto)->element_type() : d_proto->type(), v))
+        return false;
 
-    // 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!");
-    }
+    m_set_cardinal_values_internal(v, sz);
+    return true;
+}
 
-    // 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!");
-    }
+template <typename T>
+bool Vector::set_value(vector<T> &v, int sz)
+{
+    // Extra call worth the overhead?
+    return set_value(&v[0], sz);
+#if 0
+    if (!v || !types_match(d_proto->type() == dods_enum_c ? static_cast<D4Enum*>(d_proto)->element_type() : d_proto->type(), v))
+        return false;
 
-    // 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(true);
-            char* pIntoBuf = _buf + (startElement * varWidth);
-            memcpy(pIntoBuf, pFromBuf, numBytesToCopy);
-        }
-            break;
+    m_set_cardinal_values_internal(&v[0], sz);
+    return true;
+#endif
+}
 
-        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;
+template bool Vector::set_value(dods_byte *val, int sz);
+template bool Vector::set_value(dods_int8 *val, int sz);
+template bool Vector::set_value(dods_int16 *val, int sz);
+template bool Vector::set_value(dods_uint16 *val, int sz);
+template bool Vector::set_value(dods_int32 *val, int sz);
+template bool Vector::set_value(dods_uint32 *val, int sz);
+template bool Vector::set_value(dods_int64 *val, int sz);
+template bool Vector::set_value(dods_uint64 *val, int sz);
+template bool Vector::set_value(dods_float32 *val, int sz);
+template bool Vector::set_value(dods_float64 *val, int sz);
+
+template bool Vector::set_value(vector<dods_byte> &val, int sz);
+template bool Vector::set_value(vector<dods_int8> &val, int sz);
+template bool Vector::set_value(vector<dods_int16> &val, int sz);
+template bool Vector::set_value(vector<dods_uint16> &val, int sz);
+template bool Vector::set_value(vector<dods_int32> &val, int sz);
+template bool Vector::set_value(vector<dods_uint32> &val, int sz);
+template bool Vector::set_value(vector<dods_int64> &val, int sz);
+template bool Vector::set_value(vector<dods_uint64> &val, int sz);
+template bool Vector::set_value(vector<dods_float32> &val, int sz);
+template bool Vector::set_value(vector<dods_float64> &val, int sz);
 
-        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;
+#if 0
+bool Vector::set_value(dods_byte *val, int sz)
+{
+	assert(var()->type() == dods_byte_c || var()->type() == dods_uint8_c);
+	assert(val);
 
-    } // switch (_var->type())
+    m_set_cardinal_values_internal<dods_byte> (val, sz);
+    return true;
 
-    // This is how many elements we copied.
-    return (unsigned int) rowMajorData.length();
+#if 0
+    // TODO Recode all of these like this and drop the bool return type?
+    if (var()->type() == dods_byte_c && val) {
+        m_set_cardinal_values_internal<dods_byte> (val, sz);
+        return true;
+    }
+    else {
+        return false;
+    }
+#endif
 }
 
-//@{
 /** @brief set the value of a byte array */
-bool Vector::set_value(dods_byte *val, int sz)
+bool Vector::set_value(vector<dods_byte> &val, int sz)
 {
-    if (var()->type() == dods_byte_c && val) {
-        set_cardinal_values_internal<dods_byte> (val, sz);
+	// TODO Drop the extra call or is it not worth the optimization cost?
+    return set_value(&val[0], sz);
+}
+
+/** @brief set the value of an int8 array */
+bool Vector::set_value(dods_int8 *val, int sz)
+{
+    if (var()->type() == dods_int8_c && val) {
+        m_set_cardinal_values_internal<dods_int8> (val, sz);
         return true;
     }
     else {
@@ -1246,17 +1655,17 @@ bool Vector::set_value(dods_byte *val, int sz)
     }
 }
 
-/** @brief set the value of a byte array */
-bool Vector::set_value(vector<dods_byte> &val, int sz)
+/** @brief set the value of an int8 array */
+bool Vector::set_value(vector<dods_int8> &val, int sz)
 {
     return set_value(&val[0], sz);
 }
 
-/** @brief set the value of a int16 array */
+/** @brief set the value of an 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);
+        m_set_cardinal_values_internal<dods_int16> (val, sz);
         return true;
     }
     else {
@@ -1264,17 +1673,17 @@ bool Vector::set_value(dods_int16 *val, int sz)
     }
 }
 
-/** @brief set the value of a int16 array */
+/** @brief set the value of an 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 */
+/** @brief set the value of an 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);
+        m_set_cardinal_values_internal<dods_int32> (val, sz);
         return true;
     }
     else {
@@ -1282,17 +1691,35 @@ bool Vector::set_value(dods_int32 *val, int sz)
     }
 }
 
-/** @brief set the value of a int32 array */
+/** @brief set the value of an int32 array */
 bool Vector::set_value(vector<dods_int32> &val, int sz)
 {
     return set_value(&val[0], sz);
 }
 
+/** @brief set the value of an int64 array */
+bool Vector::set_value(dods_int64 *val, int sz)
+{
+    if (var()->type() == dods_int64_c && val) {
+        m_set_cardinal_values_internal<dods_int64> (val, sz);
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+/** @brief set the value of an int64 array */
+bool Vector::set_value(vector<dods_int64> &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);
+        m_set_cardinal_values_internal<dods_uint16> (val, sz);
         return true;
     }
     else {
@@ -1310,7 +1737,7 @@ bool Vector::set_value(vector<dods_uint16> &val, int sz)
 bool Vector::set_value(dods_uint32 *val, int sz)
 {
     if (var()->type() == dods_uint32_c && val) {
-        set_cardinal_values_internal<dods_uint32> (val, sz);
+        m_set_cardinal_values_internal<dods_uint32> (val, sz);
         return true;
     }
     else {
@@ -1324,11 +1751,29 @@ bool Vector::set_value(vector<dods_uint32> &val, int sz)
     return set_value(&val[0], sz);
 }
 
+/** @brief set the value of a uint64 array */
+bool Vector::set_value(dods_uint64 *val, int sz)
+{
+    if (var()->type() == dods_uint64_c && val) {
+        m_set_cardinal_values_internal<dods_uint64> (val, sz);
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+/** @brief set the value of a uint64 array */
+bool Vector::set_value(vector<dods_uint64> &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);
+        m_set_cardinal_values_internal<dods_float32> (val, sz);
         return true;
     }
     else {
@@ -1346,7 +1791,7 @@ bool Vector::set_value(vector<dods_float32> &val, int sz)
 bool Vector::set_value(dods_float64 *val, int sz)
 {
     if (var()->type() == dods_float64_c && val) {
-        set_cardinal_values_internal<dods_float64> (val, sz);
+        m_set_cardinal_values_internal<dods_float64> (val, sz);
         return true;
     }
     else {
@@ -1359,13 +1804,14 @@ bool Vector::set_value(vector<dods_float64> &val, int sz)
 {
     return set_value(&val[0], sz);
 }
+#endif
 
 /** @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;
+        d_capacity = sz;
         for (register int t = 0; t < sz; t++) {
             d_str[t] = val[t];
         }
@@ -1383,7 +1829,7 @@ 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;
+        d_capacity = sz;
         for (register int t = 0; t < sz; t++) {
             d_str[t] = val[t];
         }
@@ -1399,30 +1845,118 @@ bool Vector::set_value(vector<string> &val, int sz)
 
 //@{
 
-/** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return.
- Read data from this variable's internal storage using the passed std::vector as an sub-setting index to the values to be returned. The
- memory referenced by \c b must point to enough memory
- to hold index.size() bytes.
+/** @brief Get a copy of the data held by this variable using the passed subsetIndex
+ * vector to identify which values to return.
+ *
+ * Read data from this variable's internal storage using the passed std::vector
+ * as an sub-setting index to the values to be returned. For example, if \c subsetIndex
+ * contains 1,3,5,7 and 9, then 'b' will contain the five values found at indexes
+ * 1,3, ..., 9.
+ *
+ * @note The memory referenced by \c b must point to enough memory to hold index.size()
+ * bytes; no test for this is performed.
+ * @note This can only be called for cardinal types.
+ *
+ * @param index A std::vector<long> where each value in the vector is the
+ * location in the Vector's internal storage from which to read the returned value.
+ * @param b A pointer to the memory to hold the data; must be at least
+ * length() * sizeof(dods_byte) in size.*/
+template <typename T>
+void Vector::value(vector<unsigned int> *indices, T *b) const
+{
+   // unsigned long currentIndex;
+#if 0
+    // Iterator version. Not tested, jhrg 8/14/13
+    for (vector<unsigned int>::iterator i = indices->begin(), e = indices->end(); i != e; ++i) {
+        unsigned long currentIndex = *i;
+        if(currentIndex > (unsigned int)length()){
+            stringstream s;
+            s << "Vector::value() - Subset index[" << i - subsetIndex->begin() <<  "] = " << currentIndex << " references a value that is " <<
+                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
+            throw Error(s.str());
+        }
+        b[i - indices->begin()] = reinterpret_cast<T*>(d_buf )[currentIndex];
+    }
+#endif
+    for (unsigned long i = 0, e = indices->size(); i < e; ++i) {
+        unsigned long currentIndex = (*indices)[i];
+        if (currentIndex > (unsigned int)length()) {
+            stringstream s;
+            s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
+                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
+            throw Error(s.str());
+        }
+        b[i] = reinterpret_cast<T*>(d_buf )[currentIndex]; // I like this version - and it works!
+    }
+}
+
+template void Vector::value(vector<unsigned int> *indices, dods_byte *b) const;
+template void Vector::value(vector<unsigned int> *indices, dods_int8 *b) const;
+template void Vector::value(vector<unsigned int> *indices, dods_int16 *b) const;
+template void Vector::value(vector<unsigned int> *indices, dods_uint16 *b) const;
+template void Vector::value(vector<unsigned int> *indices, dods_int32 *b) const;
+template void Vector::value(vector<unsigned int> *indices, dods_uint32 *b) const;
+template void Vector::value(vector<unsigned int> *indices, dods_int64 *b) const;
+template void Vector::value(vector<unsigned int> *indices, dods_uint64 *b) const;
+template void Vector::value(vector<unsigned int> *indices, dods_float32 *b) const;
+template void Vector::value(vector<unsigned int> *indices, dods_float64 *b) const;
 
- @param index A std::vector<long> where each value in the vector is the location in the Vector's internal storage from which to read the returned value
- @param b A pointer to the memory to hold the data; must be at least
- length() * sizeof(dods_byte) in size.*/
+#if 0
 void Vector::value(vector<unsigned int> *subsetIndex, dods_byte *b) const
 {
-    unsigned long currentIndex;
-
+   // unsigned long currentIndex;
+#if 0
+	// Iterator version. Not tested, jhrg 8/14/13
+	for (vector<unsigned int>::iterator i = subsetIndex->begin(); i != subsetIndex->end(); ++i) {
+		unsigned long currentIndex = *i;
+        if(currentIndex > (unsigned int)length()){
+            stringstream s;
+            s << "Vector::value() - Subset index[" << i - subsetIndex->begin() <<  "] = " << currentIndex << " references a value that is " <<
+                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
+            throw Error(s.str());
+        }
+        b[i] = reinterpret_cast<dods_byte*>(d_buf )[currentIndex];
+	}
+#endif
     for(unsigned long i=0; i<subsetIndex->size() ;++i){
-        currentIndex = (*subsetIndex)[i] ;
+    	unsigned long currentIndex = (*subsetIndex)[i] ;
         if(currentIndex> (unsigned int)length()){
             stringstream s;
             s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
                     "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
             throw Error(s.str());
         }
-        b[i] = reinterpret_cast<dods_byte*>(_buf )[currentIndex]; // I like this version - and it works!
+        b[i] = reinterpret_cast<dods_byte*>(d_buf )[currentIndex]; // I like this version - and it works!
     }
 }
 
+void Vector::value(vector<unsigned int> *subsetIndex, dods_int8 *b) const
+{
+   // unsigned long currentIndex;
+#if 0
+	// Iterator version. Not tested, jhrg 8/14/13
+	for (vector<unsigned int>::iterator i = subsetIndex->begin(); i != subsetIndex->end(); ++i) {
+		unsigned long currentIndex = *i;
+        if(currentIndex > (unsigned int)length()){
+            stringstream s;
+            s << "Vector::value() - Subset index[" << i - subsetIndex->begin() <<  "] = " << currentIndex << " references a value that is " <<
+                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
+            throw Error(s.str());
+        }
+        b[i] = reinterpret_cast<dods_byte*>(d_buf )[currentIndex];
+	}
+#endif
+    for(unsigned long i=0; i<subsetIndex->size() ;++i){
+    	unsigned long currentIndex = (*subsetIndex)[i] ;
+        if(currentIndex> (unsigned int)length()){
+            stringstream s;
+            s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
+                    "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
+            throw Error(s.str());
+        }
+        b[i] = reinterpret_cast<dods_int8*>(d_buf )[currentIndex]; // I like this version - and it works!
+    }
+}
 
 /** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return. **/
 void Vector::value(vector<unsigned int> *subsetIndex, dods_uint16 *b) const
@@ -1437,7 +1971,7 @@ void Vector::value(vector<unsigned int> *subsetIndex, dods_uint16 *b) const
                     "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
             throw Error(s.str());
         }
-        b[i] = reinterpret_cast<dods_uint16*>(_buf )[currentIndex]; // I like this version - and it works!
+        b[i] = reinterpret_cast<dods_uint16*>(d_buf )[currentIndex]; // I like this version - and it works!
     }
 }
 
@@ -1455,7 +1989,7 @@ void Vector::value(vector<unsigned int> *subsetIndex, dods_int16 *b) const
                     "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
             throw Error(s.str());
         }
-        b[i] = reinterpret_cast<dods_int16*>(_buf )[currentIndex]; // I like this version - and it works!
+        b[i] = reinterpret_cast<dods_int16*>(d_buf )[currentIndex]; // I like this version - and it works!
     }
 }
 
@@ -1472,7 +2006,7 @@ void Vector::value(vector<unsigned int> *subsetIndex, dods_uint32 *b) const
                     "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
             throw Error(s.str());
         }
-        b[i] = reinterpret_cast<dods_uint32*>(_buf )[currentIndex]; // I like this version - and it works!
+        b[i] = reinterpret_cast<dods_uint32*>(d_buf )[currentIndex]; // I like this version - and it works!
     }
 }
 
@@ -1489,7 +2023,7 @@ void Vector::value(vector<unsigned int> *subsetIndex, dods_int32 *b) const
                     "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
             throw Error(s.str());
         }
-        b[i] = reinterpret_cast<dods_int32*>(_buf )[currentIndex]; // I like this version - and it works!
+        b[i] = reinterpret_cast<dods_int32*>(d_buf )[currentIndex]; // I like this version - and it works!
     }
 }
 
@@ -1500,20 +2034,14 @@ void Vector::value(vector<unsigned int> *subsetIndex, dods_float32 *b) const
 
     for(unsigned long i=0; i<subsetIndex->size() ;++i){
         currentIndex = (*subsetIndex)[i] ;
-        //cerr << "currentIndex: " << currentIndex << endl;
         if(currentIndex> (unsigned int)length()){
             stringstream s;
             s << "Vector::value() - Subset index[" << i <<  "] = " << currentIndex << " references a value that is " <<
                     "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
             throw Error(s.str());
         }
-        // b[i] = *reinterpret_cast<dods_float32*>(_buf ) + currentIndex; // BROKEN
-        // b[i] = *(reinterpret_cast<dods_float32*>(_buf ) + currentIndex); // Works but I like other forms
-        // b[i] = ((dods_float32*)_buf )[currentIndex]; // Works but isn't as 'safe'
-
-        b[i] = reinterpret_cast<dods_float32*>(_buf )[currentIndex]; // I like this version - and it works!
 
-        //cerr << "b[" << i << "]=" <<  b[i] << endl;
+        b[i] = reinterpret_cast<dods_float32*>(d_buf )[currentIndex];
     }
 }
 
@@ -1530,17 +2058,17 @@ void Vector::value(vector<unsigned int> *subsetIndex, dods_float64 *b) const
                     "outside the bounds of the internal storage [ length()= " << length() << " ] name: '" << name() << "'. ";
             throw Error(s.str());
         }
-        b[i] = reinterpret_cast<dods_float64*>(_buf )[currentIndex]; // I like this version - and it works!
+        b[i] = reinterpret_cast<dods_float64*>(d_buf )[currentIndex]; // I like this version - and it works!
     }
 }
-
+#endif
 
 /** @brief Get a copy of the data held by this variable using the passed subsetIndex vector to identify which values to return. **/
 void Vector::value(vector<unsigned int> *subsetIndex, vector<string> &b) const
 {
     unsigned long currentIndex;
 
-    if (_var->type() == dods_str_c || _var->type() == dods_url_c){
+    if (d_proto->type() == dods_str_c || d_proto->type() == dods_url_c){
         for(unsigned long i=0; i<subsetIndex->size() ;++i){
             currentIndex = (*subsetIndex)[i] ;
             if(currentIndex > (unsigned int)length()){
@@ -1554,12 +2082,27 @@ void Vector::value(vector<unsigned int> *subsetIndex, vector<string> &b) const
     }
 }
 
+template <typename T>
+void Vector::value(T *v) const
+{
+    // Only copy if v is not null and the proto's  type matches.
+    // For Enums, use the element type since type == dods_enum_c.
+    if (v && types_match(d_proto->type() == dods_enum_c ? static_cast<D4Enum*>(d_proto)->element_type() : d_proto->type(), v))
+        memcpy(v, d_buf, length() * sizeof(T));
+}
 
+template void Vector::value(dods_byte *v) const;
+template void Vector::value(dods_int8 *v) const;
+template void Vector::value(dods_int16 *v) const;
+template void Vector::value(dods_uint16 *v) const;
+template void Vector::value(dods_int32 *v) const;
+template void Vector::value(dods_uint32 *v) const;
+template void Vector::value(dods_int64 *v) const;
+template void Vector::value(dods_uint64 *v) const;
+template void Vector::value(dods_float32 *v) const;
+template void Vector::value(dods_float64 *v) const;
 
-
-
-
-
+#if 0
 /** @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
@@ -1569,73 +2112,98 @@ void Vector::value(vector<unsigned int> *subsetIndex, vector<string> &b) const
  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));
+    if (b && d_proto->type() == dods_byte_c) {
+        memcpy(b, d_buf, length() * sizeof(dods_byte));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(dods_int8 *b) const
+{
+    if (b && d_proto->type() == dods_int8_c) {
+        memcpy(b, d_buf, length() * sizeof(dods_int8));
     }
 }
 
 /** @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));
+    if (b && d_proto->type() == dods_uint16_c) {
+        memcpy(b, d_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));
+    if (b && d_proto->type() == dods_int16_c) {
+        memcpy(b, d_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));
+    if (b && d_proto->type() == dods_uint32_c) {
+        memcpy(b, d_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));
+    if (b && d_proto->type() == dods_int32_c) {
+        memcpy(b, d_buf, length() * sizeof(dods_int32));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(dods_uint64 *b) const
+{
+    if (b && d_proto->type() == dods_uint64_c) {
+        memcpy(b, d_buf, length() * sizeof(dods_uint64));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(dods_int64 *b) const
+{
+    if (b && d_proto->type() == dods_int64_c) {
+        memcpy(b, d_buf, length() * sizeof(dods_int64));
     }
 }
 
 /** @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));
+    if (b && d_proto->type() == dods_float32_c) {
+        memcpy(b, d_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));
+    if (b && d_proto->type() == dods_float64_c) {
+        memcpy(b, d_buf, length() * sizeof(dods_float64));
     }
 }
+#endif
 
 /** @brief Get a copy of the data held by this variable. */
 void Vector::value(vector<string> &b) const
 {
-    if (_var->type() == dods_str_c || _var->type() == dods_url_c)
+    if (d_proto->type() == dods_str_c || d_proto->type() == dods_url_c)
         b = d_str;
 }
 
-/** Allocated memory and copy data into the new buffer. Return the new
+/** Allocate 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(true)];
 
-    memcpy(buffer, _buf, width(true));
+    memcpy(buffer, d_buf, width(true));
 
     return buffer;
 }
@@ -1656,93 +2224,60 @@ void *Vector::value()
  @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)
+void Vector::add_var(BaseType * v, Part /*p*/)
 {
 #if 0
-    if (v && v->is_dap4_only_type())
-        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Vector.");
-#endif
-    // Delete the current template variable
-    if (_var) {
-        delete _var;
-        _var = 0;
+	//TODO Why doesn't this work?  tried all 3 variants. jhrg 8/14/13
+	Vector::add_var_nocopy(v->ptr_duplicate(), p);
+	add_var_nocopy(v->ptr_duplicate(), p);
+	add_var_nocopy(v->ptr_duplicate());
+#else
+	// Delete the current template variable
+    if (d_proto) {
+        delete d_proto;
+        d_proto = 0;
     }
 
     // if 'v' is null, just set _var to null and exit.
     if (!v) {
-        _var = 0;
+        d_proto = 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();
+        d_proto = 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
+        // If 'v' has a name, use it as the name of the array. If v doesn't have
+        // a name, then make sure to copy the array's name to it
         // 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());
+            d_proto->set_name(name());
 
-        _var->set_parent(this); // Vector --> child
+        d_proto->set_parent(this); // Vector --> child
 
         DBG(cerr << "Vector::add_var: Added variable " << v << " ("
                 << v->name() << " " << v->type_name() << ")" << endl);
     }
-}
-
-void Vector::add_var_nocopy(BaseType * v, Part)
-{
-#if 0
-    if (v && v->is_dap4_only_type())
-        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Vector.");
 #endif
-    // 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 {
-        _var = v;
-
-        // 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);
-    }
 }
 
-#if 0
-// branch version
 void Vector::add_var_nocopy(BaseType * v, Part)
 {
-    // Delete the current template variable
-    if (_var) {
-        delete _var;
-        _var = 0;
+	// Delete the current template variable
+    if (d_proto) {
+        delete d_proto;
+        d_proto = 0;
     }
 
     // if 'v' is null, just set _var to null and exit.
     if (!v) {
-        _var = 0;
+        d_proto = 0;
     }
     else {
-        _var = v;
+        d_proto = v;
 
         // 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
@@ -1750,15 +2285,14 @@ void Vector::add_var_nocopy(BaseType * v, Part)
         if (!v->name().empty())
             set_name(v->name());
         else
-            _var->set_name(name());
+            d_proto->set_name(name());
 
-        _var->set_parent(this); // Vector --> child
+        d_proto->set_parent(this); // Vector is the parent; proto is the child
 
-        DBG(cerr << "Vector::add_var: Added variable " << v << " ("
+        DBG(cerr << "Vector::add_var_no_copy: Added variable " << v << " ("
                 << v->name() << " " << v->type_name() << ")" << endl);
     }
 }
-#endif
 
 bool Vector::check_semantics(string & msg, bool)
 {
@@ -1779,10 +2313,10 @@ void Vector::dump(ostream &strm) const
     DapIndent::Indent();
     BaseType::dump(strm);
     strm << DapIndent::LMarg << "# elements in vector: " << d_length << endl;
-    if (_var) {
+    if (d_proto) {
         strm << DapIndent::LMarg << "base type:" << endl;
         DapIndent::Indent();
-        _var->dump(strm);
+        d_proto->dump(strm);
         DapIndent::UnIndent();
     }
     else {
@@ -1790,9 +2324,9 @@ void Vector::dump(ostream &strm) const
     }
     strm << DapIndent::LMarg << "vector contents:" << endl;
     DapIndent::Indent();
-    for (unsigned i = 0; i < _vec.size(); ++i) {
-        if (_vec[i])
-            _vec[i]->dump(strm);
+    for (unsigned i = 0; i < d_compound_buf.size(); ++i) {
+        if (d_compound_buf[i])
+            d_compound_buf[i]->dump(strm);
         else
             strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl;
     }
@@ -1803,16 +2337,17 @@ void Vector::dump(ostream &strm) const
         strm << DapIndent::LMarg << d_str[i] << endl;
     }
     DapIndent::UnIndent();
-    if (_buf) {
-        switch (_var->type()) {
-            case dods_byte_c: {
+    if (d_buf) {
+        switch (d_proto->type()) {
+            case dods_byte_c:
+            case dods_char_c: {
                 strm << DapIndent::LMarg << "_buf: ";
-                strm.write(_buf, d_length);
+                strm.write(d_buf, d_length);
                 strm << endl;
             }
                 break;
             default: {
-                strm << DapIndent::LMarg << "_buf: " << (void *) _buf << endl;
+                strm << DapIndent::LMarg << "_buf: " << (void *) d_buf << endl;
             }
                 break;
         }
diff --git a/Vector.h b/Vector.h
index 329ac53..d5a056c 100644
--- a/Vector.h
+++ b/Vector.h
@@ -47,6 +47,8 @@
 #include "ConstraintEvaluator.h"
 #endif
 
+class Crc32;
+
 namespace libdap
 {
 
@@ -78,32 +80,32 @@ namespace libdap
 class Vector: public BaseType
 {
 private:
-    int d_length;  // number of elements in the vector
-    BaseType *_var;  // base type of the Vector
+    int d_length;  		// number of elements in the vector
+    BaseType *d_proto;  // element prototype for 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
+    char *d_buf;   		// storage for cardinal data
+    vector<string> d_str;		// special storage for strings. jhrg 2/11/05
+    vector<BaseType *> d_compound_buf; 	// storage for data in compound types (e.g., Structure)
 
     // the number of elements we have allocated memory to store.
     // This should be either the sizeof(buf)/width(bool constrained = false) for cardinal data
     // or the capacity of d_str for strings or capacity of _vec.
-    unsigned int _capacity;
+    unsigned int d_capacity;
 
 protected:
     // This function copies the private members of Vector.
-    void _duplicate(const Vector &v);
+    void m_duplicate(const Vector &v);
 
     bool m_is_cardinal_type() const;
     unsigned int m_create_cardinal_data_buffer_for_type(unsigned int numEltsOfType);
     void m_delete_cardinal_data_buffer();
 
-    template <class CardType> void set_cardinal_values_internal(const CardType* fromArray, int numElts);
+    template <class CardType> void m_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 string &n, BaseType *v, const Type &t, bool is_dap4 = false);
+    Vector(const string &n, const string &d, BaseType *v, const Type &t, bool is_dap4 = false);
     Vector(const Vector &rhs);
 
     virtual ~Vector();
@@ -111,7 +113,11 @@ public:
     Vector &operator=(const Vector &rhs);
     virtual BaseType *ptr_duplicate() = 0;
 
+#if 0
     virtual bool is_dap2_only_type();
+#endif
+
+    virtual BaseType *prototype() const { return d_proto; }
 
     virtual void set_name(const std::string& name);
 
@@ -121,21 +127,28 @@ public:
 
     virtual void set_read_p(bool state);
 
-    virtual unsigned int width(bool constrained = false);
+    virtual unsigned int width(bool constrained = false) const;
 
     virtual int length() const;
 
     virtual void set_length(int l);
 
+    // DAP2
     virtual void intern_data(ConstraintEvaluator &eval, DDS &dds);
-    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
-			   Marshaller &m, bool ce_eval = true);
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval = true);
     virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
 
+    // DAP4
+    virtual void compute_checksum(Crc32 &checksum);
+    virtual void intern_data(Crc32 &checksum/*, DMR &dmr, ConstraintEvaluator &eval*/);
+    virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
+    virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
+
     virtual unsigned int val2buf(void *val, bool reuse = false);
     virtual unsigned int buf2val(void **val);
 
     void set_vec(unsigned int i, BaseType *val);
+    void set_vec_nocopy(unsigned int i, BaseType * val);
 
     void vec_resize(int l);
 
@@ -145,48 +158,75 @@ public:
     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 unsigned int set_value_slice_from_row_major_vector(const Vector& rowMajorData, unsigned int startElement);
 
+    template <typename T> bool set_value(T *v, int sz);
+    template <typename T> bool set_value(vector<T> &v, int sz);
+#if 0
     virtual bool set_value(dods_byte *val, int sz);
     virtual bool set_value(vector<dods_byte> &val, int sz);
+
+    virtual bool set_value(dods_int8 *val, int sz);
+    virtual bool set_value(vector<dods_int8> &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_int64 *val, int sz);
+    virtual bool set_value(vector<dods_int64> &val, int sz);
+
+    virtual bool set_value(dods_uint64 *val, int sz);
+    virtual bool set_value(vector<dods_uint64> &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);
+#endif
     virtual bool set_value(string *val, int sz);
     virtual bool set_value(vector<string> &val, int sz);
 
+    template <typename T> void value(T *v) const;
+#if 0
     virtual void value(dods_byte *b) const;
+    virtual void value(dods_int8 *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_int64 *b) const;
+    virtual void value(dods_uint64 *b) const;
     virtual void value(dods_float32 *b) const;
     virtual void value(dods_float64 *b) const;
+#endif
     virtual void value(vector<string> &b) const;
 
+    template <typename T> void value(vector<unsigned int> *indices, T *b) const;
+#if 0
     void value(vector<unsigned int> *index, dods_byte *b) const;
+    void value(vector<unsigned int> *index, dods_int8 *b) const;
     void value(vector<unsigned int> *index, dods_int16 *b) const;
     void value(vector<unsigned int> *index, dods_uint16 *b) const;
     void value(vector<unsigned int> *index, dods_int32 *b) const;
     void value(vector<unsigned int> *index, dods_uint32 *b) const;
     void value(vector<unsigned int> *index, dods_float32 *b) const;
     void value(vector<unsigned int> *index, dods_float64 *b) const;
+#endif
     void value(vector<unsigned int> *index, 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 = "", bool exact_match = true, btp_stack *s = 0);
     virtual BaseType *var(const string &name, btp_stack &s);
     virtual BaseType *var(unsigned int i);
 
diff --git a/XDRFileMarshaller.cc b/XDRFileMarshaller.cc
index b810b0b..9ba97f4 100644
--- a/XDRFileMarshaller.cc
+++ b/XDRFileMarshaller.cc
@@ -30,6 +30,8 @@
 // Authors:
 //      pwest       Patrick West <pwest at ucar.edu>
 
+#include "config.h"
+
 #include "XDRFileMarshaller.h"
 
 #include "Byte.h"
diff --git a/XDRFileUnMarshaller.cc b/XDRFileUnMarshaller.cc
index 7741fa7..1185e70 100644
--- a/XDRFileUnMarshaller.cc
+++ b/XDRFileUnMarshaller.cc
@@ -30,6 +30,8 @@
 // Authors:
 //      pwest       Patrick West <pwest at ucar.edu>
 
+#include "config.h"
+
 #include "XDRFileUnMarshaller.h"
 
 #include "Byte.h"
diff --git a/XDRStreamMarshaller.cc b/XDRStreamMarshaller.cc
index af25e23..5b5b99b 100644
--- a/XDRStreamMarshaller.cc
+++ b/XDRStreamMarshaller.cc
@@ -30,6 +30,8 @@
 // Authors:
 //      pwest       Patrick West <pwest at ucar.edu>
 
+#include "config.h"
+
 #include "XDRStreamMarshaller.h"
 
 #include <iostream>
@@ -58,15 +60,13 @@ char *XDRStreamMarshaller::d_buf = 0;
  * @param checksum If true, compute checksums. False by default
  * @param write_data If true, write data values. True by default
  */
-XDRStreamMarshaller::XDRStreamMarshaller(ostream &out) : // , bool checksum, bool write_data) :
-    /*&d_sink(0),*/ d_out(out)//, _MD_CTX(0), _write_data(write_data), _checksum_ctx_valid(false)
+XDRStreamMarshaller::XDRStreamMarshaller(ostream &out) : d_out(out)
 {
     if (!d_buf)
         d_buf = (char *) malloc(XDR_DAP_BUFF_SIZE);
     if (!d_buf)
         throw Error("Failed to allocate memory for data serialization.");
 
-    //&d_sink = new XDR;
     xdrmem_create( &d_sink, d_buf, XDR_DAP_BUFF_SIZE, XDR_ENCODE);
 
 #if CHECKSUMS
@@ -77,13 +77,13 @@ XDRStreamMarshaller::XDRStreamMarshaller(ostream &out) : // , bool checksum, boo
 }
 
 XDRStreamMarshaller::XDRStreamMarshaller() :
-    Marshaller(), /*&d_sink(0),*/ d_out(cout)
+    Marshaller(), d_out(cout)
 {
     throw InternalErr(__FILE__, __LINE__, "Default constructor not implemented.");
 }
 
 XDRStreamMarshaller::XDRStreamMarshaller(const XDRStreamMarshaller &m) :
-    Marshaller(m), /*&d_sink(0),*/ d_out(cout)
+    Marshaller(m), d_out(cout)
 {
     throw InternalErr(__FILE__, __LINE__, "Copy constructor not implemented.");
 }
@@ -98,9 +98,7 @@ XDRStreamMarshaller::operator=(const XDRStreamMarshaller &)
 
 XDRStreamMarshaller::~XDRStreamMarshaller()
 {
-    xdr_destroy(&d_sink); //delete_xdrstdio(&d_sink);
-    //delete(&d_sink);
-    //&d_sink = 0;
+    xdr_destroy(&d_sink);
 
 #if CHECKSUMS
     if (_MD_CTX)
@@ -185,7 +183,6 @@ void XDRStreamMarshaller::put_byte(dods_byte val)
     if (_MD_CTX)
         checksum_update(&val, sizeof(dods_byte));
 #endif
-//    if (_write_data) {
     DBG( std::cerr << "put_byte: " << val << std::endl );
 
     if (!xdr_setpos( &d_sink, 0 ))
@@ -199,7 +196,6 @@ void XDRStreamMarshaller::put_byte(dods_byte val)
         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.");
 
     d_out.write(d_buf, bytes_written);
-//    }
 }
 
 void XDRStreamMarshaller::put_int16(dods_int16 val)
@@ -208,7 +204,6 @@ void XDRStreamMarshaller::put_int16(dods_int16 val)
     if (_MD_CTX)
         checksum_update(&val, sizeof(dods_int16));
 #endif
-//    if (_write_data) {
     if (!xdr_setpos( &d_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.");
 
@@ -220,7 +215,6 @@ void XDRStreamMarshaller::put_int16(dods_int16 val)
         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.");
 
     d_out.write(d_buf, bytes_written);
-//    }
 }
 
 void XDRStreamMarshaller::put_int32(dods_int32 val)
@@ -229,7 +223,6 @@ void XDRStreamMarshaller::put_int32(dods_int32 val)
     if (_MD_CTX)
         checksum_update(&val, sizeof(dods_int32));
 #endif
-//    if (_write_data) {
     if (!xdr_setpos( &d_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.");
 
@@ -241,7 +234,6 @@ void XDRStreamMarshaller::put_int32(dods_int32 val)
         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.");
 
     d_out.write(d_buf, bytes_written);
-//    }
 }
 
 void XDRStreamMarshaller::put_float32(dods_float32 val)
@@ -250,7 +242,6 @@ void XDRStreamMarshaller::put_float32(dods_float32 val)
     if (_MD_CTX)
         checksum_update(&val, sizeof(dods_float32));
 #endif
-//    if (_write_data) {
     if (!xdr_setpos( &d_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.");
 
@@ -262,7 +253,6 @@ void XDRStreamMarshaller::put_float32(dods_float32 val)
         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.");
 
     d_out.write(d_buf, bytes_written);
-//    }
 }
 
 void XDRStreamMarshaller::put_float64(dods_float64 val)
@@ -271,7 +261,6 @@ void XDRStreamMarshaller::put_float64(dods_float64 val)
     if (_MD_CTX)
         checksum_update(&val, sizeof(dods_float64));
 #endif
-//    if (_write_data) {
     if (!xdr_setpos( &d_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.");
 
@@ -283,7 +272,6 @@ void XDRStreamMarshaller::put_float64(dods_float64 val)
         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.");
 
     d_out.write(d_buf, bytes_written);
-//    }
 }
 
 void XDRStreamMarshaller::put_uint16(dods_uint16 val)
@@ -292,7 +280,6 @@ void XDRStreamMarshaller::put_uint16(dods_uint16 val)
     if (_MD_CTX)
         checksum_update(&val, sizeof(dods_uint16));
 #endif
-//    if (_write_data) {
     if (!xdr_setpos( &d_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.");
 
@@ -304,7 +291,6 @@ void XDRStreamMarshaller::put_uint16(dods_uint16 val)
         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.");
 
     d_out.write(d_buf, bytes_written);
-//    }
 }
 
 void XDRStreamMarshaller::put_uint32(dods_uint32 val)
@@ -313,7 +299,6 @@ void XDRStreamMarshaller::put_uint32(dods_uint32 val)
     if (_MD_CTX)
         checksum_update(&val, sizeof(dods_uint32));
 #endif
-//    if (_write_data) {
     if (!xdr_setpos( &d_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.");
 
@@ -325,7 +310,6 @@ void XDRStreamMarshaller::put_uint32(dods_uint32 val)
         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.");
 
     d_out.write(d_buf, bytes_written);
-//    }
 }
 
 void XDRStreamMarshaller::put_str(const string &val)
@@ -384,7 +368,6 @@ void XDRStreamMarshaller::put_opaque(char *val, unsigned int len)
     if (_MD_CTX)
         checksum_update(&val, len);
 #endif
-//    if (_write_data) {
     if (len > XDR_DAP_BUFF_SIZE)
         throw Error("Network I/O Error. Could not send opaque data - length of opaque data larger than allowed");
 
@@ -399,7 +382,6 @@ void XDRStreamMarshaller::put_opaque(char *val, unsigned int len)
         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.");
 
     d_out.write(d_buf, bytes_written);
-//    }
 }
 
 void XDRStreamMarshaller::put_int( int val )
@@ -408,7 +390,6 @@ void XDRStreamMarshaller::put_int( int val )
     if (_MD_CTX)
         checksum_update(&val, sizeof(int));
 #endif
-//    if (_write_data) {
     if (!xdr_setpos( &d_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.");
 
@@ -420,7 +401,6 @@ void XDRStreamMarshaller::put_int( int val )
         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.");
 
     d_out.write(d_buf, bytes_written);
-//    }
 }
 
 void XDRStreamMarshaller::put_vector(char *val, int num, Vector &)
@@ -430,6 +410,7 @@ void XDRStreamMarshaller::put_vector(char *val, int num, Vector &)
 	if (_MD_CTX)
 	checksum_update(val, num);
 #endif
+	// 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.
@@ -479,6 +460,7 @@ void XDRStreamMarshaller::put_vector(char *val, unsigned int num, int width, Typ
 	if (_MD_CTX)
 	checksum_update(val, num * width);
 #endif
+	// write the number of array members being written, then set the position back to 0
 	put_int(num);
 
 	int use_width = width;
diff --git a/XDRUtils.cc b/XDRUtils.cc
index 867b6f3..dfd84f6 100644
--- a/XDRUtils.cc
+++ b/XDRUtils.cc
@@ -30,6 +30,8 @@
 // Authors:
 //      pwest       Patrick West <pwest at ucar.edu>
 
+#include "config.h"
+
 #include "XDRUtils.h"
 #include "debug.h"
 #include "Str.h"
@@ -170,9 +172,10 @@ XDRUtils::xdr_coder( const Type &t )
 	case dods_sequence_c:
 	case dods_grid_c:
 	default:
-	    return NULL ;
 	    break ;
     }
+
+    return NULL;
 }
 
 } // namespace libdap
diff --git a/XMLWriter.cc b/XMLWriter.cc
index 8e7e46a..b2585a9 100644
--- a/XMLWriter.cc
+++ b/XMLWriter.cc
@@ -28,6 +28,8 @@
  *      Author: jimg
  */
 
+#include "config.h"
+
 #include "XMLWriter.h"
 
 #include <libxml/encoding.h>
diff --git a/XMLWriter.h b/XMLWriter.h
index bf8baf5..4c80cca 100644
--- a/XMLWriter.h
+++ b/XMLWriter.h
@@ -35,9 +35,7 @@
 
 #include <string>
 
-#include <InternalErr.h>
-
-using namespace std;
+namespace libdap {
 
 class XMLWriter {
 private:
@@ -47,12 +45,12 @@ private:
     bool d_started;
     bool d_ended;
 
-    string d_doc;
+    std::string d_doc;
 
     void m_cleanup() ;
 
 public:
-    XMLWriter(const string &pad = "    ");
+    XMLWriter(const std::string &pad = "    ");
     virtual ~XMLWriter();
 
     xmlTextWriterPtr get_writer() { return d_writer; }
@@ -60,4 +58,6 @@ public:
     unsigned int get_doc_size();
 };
 
+} // namespace libdap
+
 #endif /* XMLWRITER_H_ */
diff --git a/abi_checker.xml.in b/abi_checker.xml.in
new file mode 100644
index 0000000..da711fb
--- /dev/null
+++ b/abi_checker.xml.in
@@ -0,0 +1,17 @@
+<!-- How to use the abi checker:
+     Build the old and new code on a machine that uses gcc
+     Run the command 'abi-compliance-checker -lib NAME -old OLD.xml -new NEW.xml'
+     where OLD.xml, ..., is this file and lib NAME is libdap, ...
+     To get the abi checker, use git clone https://github.com/lvc/abi-compliance-checker -->
+     
+<version>
+    @PACKAGE_VERSION@
+</version>
+
+<headers>
+    @abs_top_srcdir@
+</headers>
+
+<libs>
+    @abs_top_builddir@/.libs
+</libs>
diff --git a/aclocal.m4 b/aclocal.m4
index cc81072..8b14627 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -670,6 +670,40 @@ AC_MSG_RESULT([$_am_result])
 rm -f confinc confmf
 ])
 
+# Copyright (C) 1999-2012 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_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
 # Copyright (C) 1997-2012 Free Software Foundation, Inc.
@@ -1010,7 +1044,9 @@ m4_include([gl/m4/btowc.m4])
 m4_include([gl/m4/byteswap.m4])
 m4_include([gl/m4/codeset.m4])
 m4_include([gl/m4/configmake.m4])
+m4_include([gl/m4/eealloc.m4])
 m4_include([gl/m4/extensions.m4])
+m4_include([gl/m4/extern-inline.m4])
 m4_include([gl/m4/fcntl-o.m4])
 m4_include([gl/m4/glibc21.m4])
 m4_include([gl/m4/gnulib-common.m4])
@@ -1018,12 +1054,16 @@ 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/lib-ld.m4])
+m4_include([gl/m4/lib-link.m4])
+m4_include([gl/m4/lib-prefix.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/locale_h.m4])
 m4_include([gl/m4/localeconv.m4])
+m4_include([gl/m4/lock.m4])
 m4_include([gl/m4/longlong.m4])
 m4_include([gl/m4/malloc.m4])
 m4_include([gl/m4/mbrtowc.m4])
@@ -1039,9 +1079,8 @@ 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/strcase.m4])
-m4_include([gl/m4/strings_h.m4])
 m4_include([gl/m4/sys_types_h.m4])
+m4_include([gl/m4/threadlib.m4])
 m4_include([gl/m4/unistd_h.m4])
 m4_include([gl/m4/warn-on-use.m4])
 m4_include([gl/m4/wchar_h.m4])
@@ -1051,6 +1090,7 @@ m4_include([gl/m4/wctype_h.m4])
 m4_include([gl/m4/wint_t.m4])
 m4_include([conf/acinclude.m4])
 m4_include([conf/cppunit.m4])
+m4_include([conf/gcov_valgrind.m4])
 m4_include([conf/libtool.m4])
 m4_include([conf/ltoptions.m4])
 m4_include([conf/ltsugar.m4])
diff --git a/ce_expr.lex b/ce_expr.lex
index 8fc9d1a..9742648 100644
--- a/ce_expr.lex
+++ b/ce_expr.lex
@@ -48,8 +48,6 @@
 
 #include "config.h"
 
-static char rcsid[] not_used = {"$Id: ce_expr.lex 27157 2013-09-28 21:22:52Z jimg $"};
-
 #include <cstdio>
 #include <string>
 #include <cstring>
diff --git a/ce_expr.tab.cc b/ce_expr.tab.cc
index 8a8f0dc..f7b1731 100644
--- a/ce_expr.tab.cc
+++ b/ce_expr.tab.cc
@@ -1,21 +1,19 @@
+/* A Bison parser, made by GNU Bison 3.0.1.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* Bison implementation for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
 
-/* 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 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 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/>.  */
 
@@ -28,7 +26,7 @@
    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.  */
 
@@ -46,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "3.0.1"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -60,29 +58,28 @@
 /* Pull parsers.  */
 #define YYPULL 1
 
-/* 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
 
+#define yylval          ce_exprlval
+#define yychar          ce_exprchar
 
 /* Copy the first part of user declarations.  */
 
+#line 75 "ce_expr.tab.cc" /* yacc.c:339  */
 
-/* Line 189 of yacc.c  */
-#line 81 "ce_expr.tab.cc"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -92,15 +89,19 @@
 # define YYERROR_VERBOSE 0
 #endif
 
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+   by #include "ce_expr.tab.hh".  */
+#ifndef YY_CE_EXPR_CE_EXPR_TAB_HH_INCLUDED
+# define YY_CE_EXPR_CE_EXPR_TAB_HH_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int ce_exprdebug;
 #endif
-
 /* "%code requires" blocks.  */
-
-/* Line 209 of yacc.c  */
-#line 41 "ce_expr.yy"
+#line 41 "ce_expr.yy" /* yacc.c:355  */
 
 
 #include "config.h"
@@ -196,45 +197,39 @@ template<class t, class T>
 rvalue *build_constant_array(vector<t> *values, DDS *dds);
 
 
+#line 201 "ce_expr.tab.cc" /* yacc.c:355  */
 
-
-/* Line 209 of yacc.c  */
-#line 203 "ce_expr.tab.cc"
-
-/* Tokens.  */
+/* Token type.  */
 #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,
-     SCAN_STAR = 267,
-     SCAN_HASH_BYTE = 268,
-     SCAN_HASH_INT16 = 269,
-     SCAN_HASH_UINT16 = 270,
-     SCAN_HASH_INT32 = 271,
-     SCAN_HASH_UINT32 = 272,
-     SCAN_HASH_FLOAT32 = 273,
-     SCAN_HASH_FLOAT64 = 274
-   };
+  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,
+    SCAN_STAR = 267,
+    SCAN_HASH_BYTE = 268,
+    SCAN_HASH_INT16 = 269,
+    SCAN_HASH_UINT16 = 270,
+    SCAN_HASH_INT32 = 271,
+    SCAN_HASH_UINT32 = 272,
+    SCAN_HASH_FLOAT32 = 273,
+    SCAN_HASH_FLOAT64 = 274
+  };
 #endif
 
-
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
 {
-
-/* Line 214 of yacc.c  */
-#line 145 "ce_expr.yy"
+#line 145 "ce_expr.yy" /* yacc.c:355  */
 
     bool boolean;
     int op;
@@ -267,35 +262,30 @@ typedef union YYSTYPE
     libdap::rvalue *rval_ptr;
     libdap::rvalue_list *r_val_l_ptr;
 
-
-
-/* Line 214 of yacc.c  */
-#line 274 "ce_expr.tab.cc"
-} YYSTYPE;
+#line 266 "ce_expr.tab.cc" /* yacc.c:355  */
+};
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
 
-/* Copy the second part of user declarations.  */
+extern YYSTYPE ce_exprlval;
 
+int ce_exprparse (ce_parser_arg *arg);
 
-/* Line 264 of yacc.c  */
-#line 286 "ce_expr.tab.cc"
-/* Unqualified %code blocks.  */
+#endif /* !YY_CE_EXPR_CE_EXPR_TAB_HH_INCLUDED  */
+
+/* Copy the second part of user declarations.  */
 
-/* Line 265 of yacc.c  */
-#line 232 "ce_expr.yy"
+#line 281 "ce_expr.tab.cc" /* yacc.c:358  */
+/* Unqualified %code blocks.  */
+#line 232 "ce_expr.yy" /* yacc.c:359  */
 
 /* This global is used by the rule 'arg_length_hint' so that the hint can 
    be used during the paraent rule's parse. See fast_int32_arg_list. */
 unsigned long arg_length_hint_value = 0;
 
-
-
-/* Line 265 of yacc.c  */
-#line 299 "ce_expr.tab.cc"
+#line 289 "ce_expr.tab.cc" /* yacc.c:359  */
 
 #ifdef short
 # undef short
@@ -309,11 +299,8 @@ typedef unsigned char yytype_uint8;
 
 #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;
+typedef signed char yytype_int8;
 #endif
 
 #ifdef YYTYPE_UINT16
@@ -333,8 +320,7 @@ typedef short int yytype_int16;
 #  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)
+# elif ! defined YYSIZE_T
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
@@ -345,41 +331,70 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(msgid) msgid
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
 #else
-# define YYUSE(e) /* empty */
+# 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 yyi)
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
 #else
-static int
-YYID (yyi)
-    int yyi;
+# define YY_INITIAL_VALUE(Value) Value
 #endif
-{
-  return yyi;
-}
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
 #endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
 
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
@@ -398,11 +413,11 @@ YYID (yyi)
 #    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)
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -410,8 +425,8 @@ YYID (yyi)
 # endif
 
 # ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+   /* Pacify GCC's 'empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (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
@@ -425,25 +440,23 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
-	     && (defined YYFREE || defined free)))
+             && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
+#   if ! defined malloc && ! defined EXIT_SUCCESS
 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)
+#   if ! defined free && ! defined EXIT_SUCCESS
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
@@ -453,7 +466,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
-	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
@@ -471,64 +484,70 @@ union yyalloc
      ((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
+# define YYCOPY_NEEDED 1
 
 /* 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_alloc, Stack)				\
-    do									\
-      {									\
-	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
-	Stack = &yyptr->Stack_alloc;					\
-	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-	yyptr += yynewbytes / sizeof (*yyptr);				\
-      }									\
-    while (YYID (0))
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
+    do                                                                  \
+      {                                                                 \
+        YYSIZE_T yynewbytes;                                            \
+        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+        Stack = &yyptr->Stack_alloc;                                    \
+        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                 \
+    while (0)
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (0)
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  28
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   157
+#define YYLAST   167
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  29
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  35
+#define YYNNTS  36
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  78
-/* YYNRULES -- Number of states.  */
-#define YYNSTATES  146
+#define YYNRULES  80
+/* YYNSTATES -- Number of states.  */
+#define YYNSTATES  149
 
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   274
 
-#define YYTRANSLATE(YYX)						\
+#define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, without out-of-bounds checking.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -562,52 +581,7 @@ static const yytype_uint8 yytranslate[] =
 };
 
 #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,    29,    36,    43,    50,    57,    64,    71,
-      78,    80,    82,    86,    88,    90,    94,    96,    98,   102,
-     104,   106,   110,   112,   114,   118,   120,   122,   126,   128,
-     130,   134,   136,   141,   143,   147,   153,   157,   159,   164,
-     166,   171,   173,   175,   179,   181,   182,   184,   186,   188,
-     191,   194,   198,   200,   202,   204,   207,   211,   215,   221,
-     227,   235,   243,   245,   247,   249,   251,   253,   255
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
-static const yytype_int8 yyrhs[] =
-{
-      30,     0,    -1,    -1,    32,    -1,    -1,    20,    31,    51,
-      -1,    32,    20,    51,    -1,    33,    -1,    33,    21,    32,
-      -1,    60,    -1,    50,    -1,    58,    -1,    34,    -1,    13,
-      22,    35,    23,    36,    24,    -1,    14,    22,    35,    23,
-      38,    24,    -1,    15,    22,    35,    23,    40,    24,    -1,
-      16,    22,    35,    23,    42,    24,    -1,    17,    22,    35,
-      23,    44,    24,    -1,    18,    22,    35,    23,    46,    24,
-      -1,    19,    22,    35,    23,    48,    24,    -1,     4,    -1,
-      37,    -1,    36,    21,    37,    -1,     4,    -1,    39,    -1,
-      38,    21,    39,    -1,     4,    -1,    41,    -1,    40,    21,
-      41,    -1,     4,    -1,    43,    -1,    42,    21,    43,    -1,
-       4,    -1,    45,    -1,    44,    21,    45,    -1,     4,    -1,
-      47,    -1,    46,    21,    47,    -1,     4,    -1,    49,    -1,
-      48,    21,    49,    -1,     4,    -1,     4,    22,    56,    24,
-      -1,    52,    -1,    51,    20,    52,    -1,    54,    63,    25,
-      55,    26,    -1,    54,    63,    54,    -1,    53,    -1,     4,
-      22,    56,    24,    -1,    57,    -1,     4,    22,    56,    24,
-      -1,    34,    -1,    54,    -1,    55,    21,    54,    -1,    55,
-      -1,    -1,     4,    -1,     3,    -1,    59,    -1,    60,    61,
-      -1,    59,    60,    -1,    59,    60,    61,    -1,     4,    -1,
-       3,    -1,    62,    -1,    61,    62,    -1,    27,     4,    28,
-      -1,    27,    12,    28,    -1,    27,     4,    23,     4,    28,
-      -1,    27,     4,    23,    12,    28,    -1,    27,     4,    23,
-       4,    23,     4,    28,    -1,    27,     4,    23,     4,    23,
-      12,    28,    -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.  */
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
        0,   241,   241,   247,   249,   249,   253,   259,   260,   266,
@@ -615,13 +589,14 @@ static const yytype_uint16 yyrline[] =
      355,   366,   370,   377,   384,   388,   395,   402,   406,   413,
      420,   424,   431,   438,   442,   449,   456,   460,   467,   474,
      478,   485,   492,   514,   515,   521,   530,   541,   548,   562,
-     563,   573,   579,   586,   595,   600,   605,   634,   650,   655,
-     664,   670,   681,   686,   697,   701,   713,   722,   729,   741,
-     752,   767,   783,   784,   785,   786,   787,   788,   789
+     563,   573,   577,   583,   590,   599,   604,   609,   647,   671,
+     684,   690,   699,   705,   716,   721,   735,   739,   753,   762,
+     769,   781,   792,   807,   823,   824,   825,   826,   827,   828,
+     829
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
@@ -640,14 +615,14 @@ static const char *const yytname[] =
   "fast_float32_arg_list", "fast_float32_arg", "fast_float64_arg_list",
   "fast_float64_arg", "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
+  "array_projection_rvalue", "array_projection", "array_proj_clause",
+  "name", "array_indices", "array_index", "rel_op", YY_NULLPTR
 };
 #endif
 
 # ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+   (internal) symbol number NUM (which must be that of a token).  */
 static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
@@ -656,249 +631,206 @@ static const yytype_uint16 yytoknum[] =
 };
 # endif
 
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    29,    30,    30,    31,    30,    30,    32,    32,    33,
-      33,    33,    33,    34,    34,    34,    34,    34,    34,    34,
-      35,    36,    36,    37,    38,    38,    39,    40,    40,    41,
-      42,    42,    43,    44,    44,    45,    46,    46,    47,    48,
-      48,    49,    50,    51,    51,    52,    52,    52,    53,    54,
-      54,    54,    55,    55,    56,    56,    57,    57,    58,    59,
-      59,    59,    60,    60,    61,    61,    62,    62,    62,    62,
-      62,    62,    63,    63,    63,    63,    63,    63,    63
-};
+#define YYPACT_NINF -57
 
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-57)))
+
+#define YYTABLE_NINF -66
+
+#define yytable_value_is_error(Yytable_value) \
+  0
+
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
+static const yytype_int16 yypact[] =
 {
-       0,     2,     0,     1,     0,     3,     3,     1,     3,     1,
-       1,     1,     1,     6,     6,     6,     6,     6,     6,     6,
-       1,     1,     3,     1,     1,     3,     1,     1,     3,     1,
-       1,     3,     1,     1,     3,     1,     1,     3,     1,     1,
-       3,     1,     4,     1,     3,     5,     3,     1,     4,     1,
-       4,     1,     1,     3,     1,     0,     1,     1,     1,     2,
-       2,     3,     1,     1,     1,     2,     3,     3,     5,     5,
-       7,     7,     1,     1,     1,     1,     1,     1,     1
+      49,   -57,    -5,    15,    24,    25,    34,    36,    64,   103,
+     -57,    28,    12,    60,   -57,   -57,   -57,     6,    -2,    57,
+      22,    22,    22,    22,    22,    22,    22,    74,   -57,    74,
+      81,   -57,    -2,     9,    -2,   -57,    21,   -15,   -57,   -57,
+     101,   102,   -57,   -57,    -2,   -57,   104,   105,   106,   107,
+     108,   109,   110,   -11,   114,   -57,   -57,    96,   114,   -57,
+      -2,     8,   111,   -57,    57,    57,   -57,    -2,   131,   132,
+     133,   134,   136,   137,   138,    57,    74,   -57,   -57,   -57,
+     -57,   -57,   -57,   -57,    26,    10,   -57,   -57,   119,   -57,
+     -57,    58,   -57,   -57,    59,   -57,   -57,    93,   -57,   -57,
+      94,   -57,   -57,    95,   -57,   -57,    99,   -57,   -57,   100,
+     -57,   120,   -57,    57,   -57,    27,   117,   -57,   131,   -57,
+     132,   -57,   133,   -57,   134,   -57,   136,   -57,   137,   -57,
+     138,   -57,     4,    33,    11,   -57,   -57,   -57,   -57,   -57,
+     -57,   -57,   -57,   -57,   -57,   118,   121,   -57,   -57
 };
 
-/* 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.  */
+  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+     Performed when YYTABLE does not specify something else to do.  Zero
+     means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       2,    63,    62,     0,     0,     0,     0,     0,     0,     0,
-       4,     0,     3,     7,    12,    10,    11,    58,     9,    55,
+       2,    65,    64,     0,     0,     0,     0,     0,     0,     0,
+       4,     0,     3,     7,    12,    10,    11,    60,     9,    56,
        0,     0,     0,     0,     0,     0,     0,     0,     1,     0,
-       0,    62,    60,     0,    59,    64,    57,    56,    51,    52,
-      54,     0,    49,    20,     0,     0,     0,     0,     0,     0,
-       0,    56,     5,    43,    47,     0,     6,     8,    61,     0,
-       0,    65,    55,     0,    42,     0,     0,     0,     0,     0,
-       0,     0,    55,     0,    72,    73,    74,    75,    76,    77,
-      78,     0,     0,    66,    67,     0,    53,    23,     0,    21,
-      26,     0,    24,    29,     0,    27,    32,     0,    30,    35,
-       0,    33,    38,     0,    36,    41,     0,    39,     0,    44,
-       0,    46,     0,     0,    50,     0,    13,     0,    14,     0,
-      15,     0,    16,     0,    17,     0,    18,     0,    19,    50,
-       0,     0,    68,    69,    22,    25,    28,    31,    34,    37,
-      40,    45,     0,     0,    70,    71
-};
-
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int8 yydefgoto[] =
-{
-      -1,    11,    27,    12,    13,    38,    44,    88,    89,    91,
-      92,    94,    95,    97,    98,   100,   101,   103,   104,   106,
-     107,    15,    52,    53,    54,    39,    40,    41,    42,    16,
-      17,    18,    34,    35,    81
+       0,    64,    62,     0,    61,    66,    58,    57,    51,    53,
+      55,     0,    49,    52,     0,    20,     0,     0,     0,     0,
+       0,     0,     0,    57,     5,    43,    47,     0,     6,     8,
+      63,     0,     0,    67,    56,     0,    42,    59,     0,     0,
+       0,     0,     0,     0,     0,    56,     0,    74,    75,    76,
+      77,    78,    79,    80,     0,     0,    68,    69,     0,    54,
+      23,     0,    21,    26,     0,    24,    29,     0,    27,    32,
+       0,    30,    35,     0,    33,    38,     0,    36,    41,     0,
+      39,     0,    44,     0,    46,     0,     0,    50,     0,    13,
+       0,    14,     0,    15,     0,    16,     0,    17,     0,    18,
+       0,    19,    50,     0,     0,    70,    71,    22,    25,    28,
+      31,    34,    37,    40,    45,     0,     0,    72,    73
 };
 
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -58
-static const yytype_int16 yypact[] =
+  /* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
 {
-      44,   -58,    -8,    56,    83,    86,    87,    88,    89,    90,
-     -58,    23,    31,    92,   -58,   -58,   -58,    73,    71,    26,
-     103,   103,   103,   103,   103,   103,   103,    52,   -58,    52,
-      69,   -58,    71,    21,    71,   -58,   -58,    93,   -58,   -58,
-      95,    94,   -58,   -58,    91,    96,    97,    98,    99,   100,
-     101,   104,   105,   -58,   -58,    85,   105,   -58,    71,     9,
-     102,   -58,    26,    26,   -58,   113,   123,   124,   125,   127,
-     128,   129,    26,    52,   -58,   -58,   -58,   -58,   -58,   -58,
-     -58,     3,    22,   -58,   -58,   110,   -58,   -58,    14,   -58,
-     -58,    28,   -58,   -58,    29,   -58,   -58,    76,   -58,   -58,
-      78,   -58,   -58,    80,   -58,   -58,    82,   -58,   111,   -58,
-      26,   -58,    51,   108,   -58,   113,   -58,   123,   -58,   124,
-     -58,   125,   -58,   127,   -58,   128,   -58,   129,   -58,     4,
-      54,    77,   -58,   -58,   -58,   -58,   -58,   -58,   -58,   -58,
-     -58,   -58,   109,   112,   -58,   -58
+     -57,   -57,   -57,   122,   -57,     5,    87,   -57,    29,   -57,
+      30,   -57,    31,   -57,    32,   -57,    35,   -57,    20,   -57,
+      37,   -57,   125,    75,   -57,   -27,    42,   -56,   -57,   -57,
+     -57,   -57,     3,   -26,   -33,   -57
 };
 
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int16 yypgoto[] =
+  /* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
 {
-     -58,   -58,   -58,   114,   -58,     1,   -13,   -58,    24,   -58,
-      25,   -58,    19,   -58,    20,   -58,    27,   -58,    18,   -58,
-      30,   -58,   116,    74,   -58,   -27,    36,   -57,   -58,   -58,
-     -58,   131,   117,   -31,   -58
+      -1,    11,    27,    12,    13,    38,    46,    91,    92,    94,
+      95,    97,    98,   100,   101,   103,   104,   106,   107,   109,
+     110,    15,    54,    55,    56,    39,    40,    41,    42,    43,
+      16,    17,    44,    34,    35,    84
 };
 
-/* 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 -49
+  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule whose
+     number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      55,    14,    55,    61,   -48,    85,    36,    37,    45,    46,
-      47,    48,    49,    50,    19,   108,     3,     4,     5,     6,
-       7,     8,     9,    28,   -48,    59,   112,    61,   110,    36,
-      37,    14,    82,    60,   113,   115,    86,    83,   116,     3,
-       4,     5,     6,     7,     8,     9,    55,     1,     2,   117,
-     119,    29,   118,   120,   111,    36,    51,     3,     4,     5,
-       6,     7,     8,     9,    10,     3,     4,     5,     6,     7,
-       8,     9,     1,     2,   131,    63,     1,    31,    20,   132,
-     141,   142,     3,     4,     5,     6,     7,     8,     9,   143,
-      74,    75,    76,    77,    78,    79,    80,   121,    33,   123,
-     122,   125,   124,   127,   126,    21,   128,    43,    22,    23,
-      24,    25,    26,    30,    65,    62,    63,    87,    64,    66,
-      67,    68,    69,    70,    71,    73,    72,    90,    93,    96,
-      84,    99,   102,   105,   114,   129,   133,   144,   136,   134,
-     145,   137,   135,   139,    57,    56,   130,   109,    32,    58,
-     138,     0,     0,     0,     0,     0,     0,   140
+      57,    63,    57,    18,   -48,    14,    60,    64,    88,     1,
+      31,    75,   -64,    61,   115,   145,   -64,    19,    67,   111,
+      32,    62,   116,   146,   -48,    33,    45,    63,    28,    36,
+      37,    85,    29,    18,    63,    14,    86,    20,    89,     3,
+       4,     5,     6,     7,     8,     9,    21,    22,   -65,    57,
+     134,   113,     1,     2,    65,   135,    23,   114,    24,   144,
+      36,    37,     3,     4,     5,     6,     7,     8,     9,    10,
+       3,     4,     5,     6,     7,     8,     9,    36,    53,   118,
+     120,    30,   119,   121,     1,     2,    25,     3,     4,     5,
+       6,     7,     8,     9,     3,     4,     5,     6,     7,     8,
+       9,    77,    78,    79,    80,    81,    82,    83,    47,    48,
+      49,    50,    51,    52,   122,   124,   126,   123,   125,   127,
+     128,   130,    65,   129,   131,    26,    66,    68,    69,    70,
+      71,    72,    73,    74,    76,    90,    93,    96,    99,    87,
+     102,   105,   108,   117,   132,   136,   147,   137,   142,   148,
+     138,   112,    59,   139,    58,   133,   140,     0,     0,     0,
+       0,   141,     0,     0,     0,     0,     0,   143
 };
 
-static const yytype_int8 yycheck[] =
+static const yytype_int16 yycheck[] =
 {
-      27,     0,    29,    34,     0,    62,     3,     4,    21,    22,
-      23,    24,    25,    26,    22,    72,    13,    14,    15,    16,
-      17,    18,    19,     0,    20,     4,     4,    58,    25,     3,
-       4,    30,    23,    12,    12,    21,    63,    28,    24,    13,
-      14,    15,    16,    17,    18,    19,    73,     3,     4,    21,
-      21,    20,    24,    24,    81,     3,     4,    13,    14,    15,
-      16,    17,    18,    19,    20,    13,    14,    15,    16,    17,
-      18,    19,     3,     4,    23,    21,     3,     4,    22,    28,
-      26,     4,    13,    14,    15,    16,    17,    18,    19,    12,
-       5,     6,     7,     8,     9,    10,    11,    21,    27,    21,
-      24,    21,    24,    21,    24,    22,    24,     4,    22,    22,
-      22,    22,    22,    21,    23,    22,    21,     4,    24,    23,
-      23,    23,    23,    23,    23,    20,    22,     4,     4,     4,
-      28,     4,     4,     4,    24,    24,    28,    28,   119,   115,
-      28,   121,   117,   125,    30,    29,   110,    73,    17,    32,
-     123,    -1,    -1,    -1,    -1,    -1,    -1,   127
+      27,    34,    29,     0,     0,     0,    32,    22,    64,     3,
+       4,    22,    27,     4,     4,     4,    27,    22,    44,    75,
+      17,    12,    12,    12,    20,    27,     4,    60,     0,     3,
+       4,    23,    20,    30,    67,    30,    28,    22,    65,    13,
+      14,    15,    16,    17,    18,    19,    22,    22,    27,    76,
+      23,    25,     3,     4,    21,    28,    22,    84,    22,    26,
+       3,     4,    13,    14,    15,    16,    17,    18,    19,    20,
+      13,    14,    15,    16,    17,    18,    19,     3,     4,    21,
+      21,    21,    24,    24,     3,     4,    22,    13,    14,    15,
+      16,    17,    18,    19,    13,    14,    15,    16,    17,    18,
+      19,     5,     6,     7,     8,     9,    10,    11,    21,    22,
+      23,    24,    25,    26,    21,    21,    21,    24,    24,    24,
+      21,    21,    21,    24,    24,    22,    24,    23,    23,    23,
+      23,    23,    23,    23,    20,     4,     4,     4,     4,    28,
+       4,     4,     4,    24,    24,    28,    28,   118,   128,    28,
+     120,    76,    30,   122,    29,   113,   124,    -1,    -1,    -1,
+      -1,   126,    -1,    -1,    -1,    -1,    -1,   130
 };
 
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
+  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+     symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
        0,     3,     4,    13,    14,    15,    16,    17,    18,    19,
-      20,    30,    32,    33,    34,    50,    58,    59,    60,    22,
+      20,    30,    32,    33,    34,    50,    59,    60,    61,    22,
       22,    22,    22,    22,    22,    22,    22,    31,     0,    20,
-      21,     4,    60,    27,    61,    62,     3,     4,    34,    54,
-      55,    56,    57,     4,    35,    35,    35,    35,    35,    35,
-      35,     4,    51,    52,    53,    54,    51,    32,    61,     4,
-      12,    62,    22,    21,    24,    23,    23,    23,    23,    23,
-      23,    23,    22,    20,     5,     6,     7,     8,     9,    10,
-      11,    63,    23,    28,    28,    56,    54,     4,    36,    37,
-       4,    38,    39,     4,    40,    41,     4,    42,    43,     4,
-      44,    45,     4,    46,    47,     4,    48,    49,    56,    52,
-      25,    54,     4,    12,    24,    21,    24,    21,    24,    21,
-      24,    21,    24,    21,    24,    21,    24,    21,    24,    24,
-      55,    23,    28,    28,    37,    39,    41,    43,    45,    47,
-      49,    26,     4,    12,    28,    28
+      21,     4,    61,    27,    62,    63,     3,     4,    34,    54,
+      55,    56,    57,    58,    61,     4,    35,    35,    35,    35,
+      35,    35,    35,     4,    51,    52,    53,    54,    51,    32,
+      62,     4,    12,    63,    22,    21,    24,    62,    23,    23,
+      23,    23,    23,    23,    23,    22,    20,     5,     6,     7,
+       8,     9,    10,    11,    64,    23,    28,    28,    56,    54,
+       4,    36,    37,     4,    38,    39,     4,    40,    41,     4,
+      42,    43,     4,    44,    45,     4,    46,    47,     4,    48,
+      49,    56,    52,    25,    54,     4,    12,    24,    21,    24,
+      21,    24,    21,    24,    21,    24,    21,    24,    21,    24,
+      21,    24,    24,    55,    23,    28,    28,    37,    39,    41,
+      43,    45,    47,    49,    26,     4,    12,    28,    28
 };
 
-#define yyerrok		(yyerrstatus = 0)
-#define yyclearin	(yychar = YYEMPTY)
-#define YYEMPTY		(-2)
-#define YYEOF		0
+  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    29,    30,    30,    31,    30,    30,    32,    32,    33,
+      33,    33,    33,    34,    34,    34,    34,    34,    34,    34,
+      35,    36,    36,    37,    38,    38,    39,    40,    40,    41,
+      42,    42,    43,    44,    44,    45,    46,    46,    47,    48,
+      48,    49,    50,    51,    51,    52,    52,    52,    53,    54,
+      54,    54,    54,    55,    55,    56,    56,    57,    57,    58,
+      59,    60,    60,    60,    61,    61,    62,    62,    63,    63,
+      63,    63,    63,    63,    64,    64,    64,    64,    64,    64,
+      64
+};
+
+  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     1,     0,     3,     3,     1,     3,     1,
+       1,     1,     1,     6,     6,     6,     6,     6,     6,     6,
+       1,     1,     3,     1,     1,     3,     1,     1,     3,     1,
+       1,     3,     1,     1,     3,     1,     1,     3,     1,     1,
+       3,     1,     4,     1,     3,     5,     3,     1,     4,     1,
+       4,     1,     1,     1,     3,     1,     0,     1,     1,     2,
+       1,     2,     2,     3,     1,     1,     1,     2,     3,     3,
+       5,     5,     7,     7,     1,     1,     1,     1,     1,     1,
+       1
+};
 
-#define YYACCEPT	goto yyacceptlab
-#define YYABORT		goto yyabortlab
-#define YYERROR		goto yyerrorlab
 
+#define yyerrok         (yyerrstatus = 0)
+#define yyclearin       (yychar = YYEMPTY)
+#define YYEMPTY         (-2)
+#define YYEOF           0
 
-/* 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 YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
 
-#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								\
-    {								\
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
       yyerror (arg, 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
+      YYERROR;                                                  \
+    }                                                           \
+while (0)
 
+/* Error token number */
+#define YYTERROR        1
+#define YYERRCODE       256
 
-/* 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
@@ -908,56 +840,47 @@ while (YYID (0))
 #  define YYFPRINTF fprintf
 # endif
 
-# define YYDPRINTF(Args)			\
-do {						\
-  if (yydebug)					\
-    YYFPRINTF Args;				\
-} while (YYID (0))
+# define YYDPRINTF(Args)                        \
+do {                                            \
+  if (yydebug)                                  \
+    YYFPRINTF Args;                             \
+} while (0)
 
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
-do {									  \
-  if (yydebug)								  \
-    {									  \
-      YYFPRINTF (stderr, "%s ", Title);					  \
-      yy_symbol_print (stderr,						  \
-		  Type, Value, arg); \
-      YYFPRINTF (stderr, "\n");						  \
-    }									  \
-} while (YYID (0))
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
+do {                                                                      \
+  if (yydebug)                                                            \
+    {                                                                     \
+      YYFPRINTF (stderr, "%s ", Title);                                   \
+      yy_symbol_print (stderr,                                            \
+                  Type, Value, arg); \
+      YYFPRINTF (stderr, "\n");                                           \
+    }                                                                     \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value 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, ce_parser_arg *arg)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    ce_parser_arg *arg;
-#endif
 {
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
+  YYUSE (arg);
   if (!yyvaluep)
     return;
-  YYUSE (arg);
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
-  YYUSE (yyoutput);
 # endif
-  switch (yytype)
-    {
-      default:
-	break;
-    }
+  YYUSE (yytype);
 }
 
 
@@ -965,23 +888,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg)
 | 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, ce_parser_arg *arg)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, arg)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    ce_parser_arg *arg;
-#endif
 {
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-  else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+  YYFPRINTF (yyoutput, "%s %s (",
+             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
   yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg);
   YYFPRINTF (yyoutput, ")");
@@ -992,16 +903,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, arg)
 | TOP (included).                                                   |
 `------------------------------------------------------------------*/
 
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
-#endif
 {
   YYFPRINTF (stderr, "Stack now");
   for (; yybottom <= yytop; yybottom++)
@@ -1012,50 +915,42 @@ yy_stack_print (yybottom, yytop)
   YYFPRINTF (stderr, "\n");
 }
 
-# define YY_STACK_PRINT(Bottom, Top)				\
-do {								\
-  if (yydebug)							\
-    yy_stack_print ((Bottom), (Top));				\
-} while (YYID (0))
+# define YY_STACK_PRINT(Bottom, Top)                            \
+do {                                                            \
+  if (yydebug)                                                  \
+    yy_stack_print ((Bottom), (Top));                           \
+} while (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, ce_parser_arg *arg)
-#else
 static void
-yy_reduce_print (yyvsp, yyrule, arg)
-    YYSTYPE *yyvsp;
-    int yyrule;
-    ce_parser_arg *arg;
-#endif
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, ce_parser_arg *arg)
 {
+  unsigned long int yylno = yyrline[yyrule];
   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);
+             yyrule - 1, yylno);
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
-		       &(yyvsp[(yyi + 1) - (yynrhs)])
-		       		       , arg);
+      yy_symbol_print (stderr,
+                       yystos[yyssp[yyi + 1 - yynrhs]],
+                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                                              , arg);
       YYFPRINTF (stderr, "\n");
     }
 }
 
-# define YY_REDUCE_PRINT(Rule)		\
-do {					\
-  if (yydebug)				\
-    yy_reduce_print (yyvsp, Rule, arg); \
-} while (YYID (0))
+# define YY_REDUCE_PRINT(Rule)          \
+do {                                    \
+  if (yydebug)                          \
+    yy_reduce_print (yyssp, yyvsp, Rule, arg); \
+} while (0)
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
    multiple parsers can coexist.  */
@@ -1069,7 +964,7 @@ int yydebug;
 
 
 /* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef	YYINITDEPTH
+#ifndef YYINITDEPTH
 # define YYINITDEPTH 200
 #endif
 
@@ -1084,7 +979,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-

 
 #if YYERROR_VERBOSE
 
@@ -1093,15 +987,8 @@ int yydebug;
 #   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++)
@@ -1117,16 +1004,8 @@ yystrlen (yystr)
 #  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;
@@ -1156,27 +1035,27 @@ yytnamerr (char *yyres, const char *yystr)
       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;
-	  }
+        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: ;
     }
 
@@ -1187,163 +1066,161 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # 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)
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
+
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
 {
-  int yyn = yypact[yystate];
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULLPTR;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
+    {
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          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 yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (! (yysize <= yysize1
+                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
+              }
+        }
+    }
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
+
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
+
+  if (*yymsg_alloc < yysize)
     {
-      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;
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
     }
+
+  /* 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 = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #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, ce_parser_arg *arg)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep, arg)
-    const char *yymsg;
-    int yytype;
-    YYSTYPE *yyvaluep;
-    ce_parser_arg *arg;
-#endif
 {
   YYUSE (yyvaluep);
   YYUSE (arg);
-
   if (!yymsg)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  switch (yytype)
-    {
-
-      default:
-	break;
-    }
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 }
 
-/* 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 (ce_parser_arg *arg);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
+
 
 
 /* The lookahead symbol.  */
@@ -1351,49 +1228,26 @@ int yychar;
 
 /* The semantic value of the lookahead symbol.  */
 YYSTYPE yylval;
-
 /* Number of syntax errors so far.  */
 int yynerrs;
 
 
+/*----------.
+| yyparse.  |
+`----------*/
 
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
-
-#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 (ce_parser_arg *arg)
-#else
-int
-yyparse (arg)
-    ce_parser_arg *arg;
-#endif
-#endif
 {
-
-
     int yystate;
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
 
     /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
+       'yyss': related to states.
+       'yyvs': related to semantic values.
 
-       Refer to the stacks thru separate pointers, to allow yyoverflow
+       Refer to the stacks through separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
 
     /* The state stack.  */
@@ -1411,7 +1265,7 @@ yyparse (arg)
   int yyn;
   int yyresult;
   /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
+  int yytoken = 0;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
@@ -1429,9 +1283,8 @@ yyparse (arg)
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
   yystacksize = YYINITDEPTH;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1440,14 +1293,6 @@ yyparse (arg)
   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;
 
 /*------------------------------------------------------------.
@@ -1468,23 +1313,23 @@ yyparse (arg)
 
 #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;
+        /* 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
@@ -1492,22 +1337,22 @@ yyparse (arg)
 # else
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
-	goto yyexhaustedlab;
+        goto yyexhaustedlab;
       yystacksize *= 2;
       if (YYMAXDEPTH < yystacksize)
-	yystacksize = YYMAXDEPTH;
+        yystacksize = YYMAXDEPTH;
 
       {
-	yytype_int16 *yyss1 = yyss;
-	union yyalloc *yyptr =
-	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-	if (! yyptr)
-	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss_alloc, yyss);
-	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+        yytype_int16 *yyss1 = yyss;
+        union yyalloc *yyptr =
+          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+        if (! yyptr)
+          goto yyexhaustedlab;
+        YYSTACK_RELOCATE (yyss_alloc, yyss);
+        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
 #  undef YYSTACK_RELOCATE
-	if (yyss1 != yyssa)
-	  YYSTACK_FREE (yyss1);
+        if (yyss1 != yyssa)
+          YYSTACK_FREE (yyss1);
       }
 # endif
 #endif /* no yyoverflow */
@@ -1516,10 +1361,10 @@ yyparse (arg)
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-		  (unsigned long int) yystacksize));
+                  (unsigned long int) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
-	YYABORT;
+        YYABORT;
     }
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1539,7 +1384,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -1548,7 +1393,7 @@ yybackup:
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = YYLEX;
+      yychar = yylex ();
     }
 
   if (yychar <= YYEOF)
@@ -1570,8 +1415,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -1588,7 +1433,9 @@ yybackup:
   yychar = YYEMPTY;
 
   yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -1611,7 +1458,7 @@ yyreduce:
   yylen = yyr2[yyn];
 
   /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
+     '$$ = $1'.
 
      Otherwise, the following line sets YYVAL to garbage.
      This behavior is undocumented and Bison
@@ -1625,91 +1472,81 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-
-/* Line 1455 of yacc.c  */
-#line 241 "ce_expr.yy"
+#line 241 "ce_expr.yy" /* yacc.c:1646  */
     {
              DBG(cerr << "Mark all variables" << endl);
 		     DDS(arg)->mark_all(true);
 		     (yyval.boolean) = true;
-		 ;}
+		 }
+#line 1482 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 4:
-
-/* Line 1455 of yacc.c  */
-#line 249 "ce_expr.yy"
-    { DDS(arg)->mark_all(true); ;}
+#line 249 "ce_expr.yy" /* yacc.c:1646  */
+    { DDS(arg)->mark_all(true); }
+#line 1488 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 5:
-
-/* Line 1455 of yacc.c  */
-#line 250 "ce_expr.yy"
+#line 250 "ce_expr.yy" /* yacc.c:1646  */
     { 
-		     (yyval.boolean) = (yyvsp[(3) - (3)].boolean);
-		 ;}
+		     (yyval.boolean) = (yyvsp[0].boolean);
+		 }
+#line 1496 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 6:
-
-/* Line 1455 of yacc.c  */
-#line 254 "ce_expr.yy"
+#line 254 "ce_expr.yy" /* yacc.c:1646  */
     {
-		     (yyval.boolean) = (yyvsp[(1) - (3)].boolean) && (yyvsp[(3) - (3)].boolean);
-		 ;}
+		     (yyval.boolean) = (yyvsp[-2].boolean) && (yyvsp[0].boolean);
+		 }
+#line 1504 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 8:
-
-/* Line 1455 of yacc.c  */
-#line 261 "ce_expr.yy"
+#line 261 "ce_expr.yy" /* yacc.c:1646  */
     {
-		     (yyval.boolean) = (yyvsp[(1) - (3)].boolean) && (yyvsp[(3) - (3)].boolean);
-		 ;}
+		     (yyval.boolean) = (yyvsp[-2].boolean) && (yyvsp[0].boolean);
+		 }
+#line 1512 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 9:
-
-/* Line 1455 of yacc.c  */
-#line 267 "ce_expr.yy"
+#line 267 "ce_expr.yy" /* yacc.c:1646  */
     {
-		     BaseType *var = DDS(arg)->var((yyvsp[(1) - (1)].id));
+		     BaseType *var = DDS(arg)->var((yyvsp[0].id));
 		     if (var) {
-			     DBG(cerr << "Marking " << (yyvsp[(1) - (1)].id) << endl);
-			     (yyval.boolean) = DDS(arg)->mark((yyvsp[(1) - (1)].id), true);
+			     DBG(cerr << "Marking " << (yyvsp[0].id) << endl);
+			     (yyval.boolean) = DDS(arg)->mark((yyvsp[0].id), true);
 			     DBG(cerr << "result: " << (yyval.boolean) << endl);
 		     }
 		     else {
-			     no_such_ident(arg, (yyvsp[(1) - (1)].id), "identifier");
+			     no_such_ident(arg, (yyvsp[0].id), "identifier");
 		     }
-		;}
+		}
+#line 1528 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 10:
-
-/* Line 1455 of yacc.c  */
-#line 279 "ce_expr.yy"
+#line 279 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    (yyval.boolean) = (yyvsp[(1) - (1)].boolean);
-		;}
+		    (yyval.boolean) = (yyvsp[0].boolean);
+		}
+#line 1536 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 11:
-
-/* Line 1455 of yacc.c  */
-#line 283 "ce_expr.yy"
+#line 283 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    (yyval.boolean) = (yyvsp[(1) - (1)].boolean);
-		;}
+		    (yyval.boolean) = (yyvsp[0].boolean);
+		}
+#line 1544 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 12:
-
-/* Line 1455 of yacc.c  */
-#line 287 "ce_expr.yy"
+#line 287 "ce_expr.yy" /* yacc.c:1646  */
     {
-            Array *array = dynamic_cast<Array*>((yyvsp[(1) - (1)].rval_ptr)->bvalue(*DDS(arg)));
+            Array *array = dynamic_cast<Array*>((yyvsp[0].rval_ptr)->bvalue(*DDS(arg)));
             if (array) { 
                 /* When the special form appears here (not as a function argument)
                 set send_p so the data will be sent and add it to the DDS. This 
@@ -1724,676 +1561,669 @@ yyreduce:
                 ce_exprerror(arg, "Could not create the anonymous vector using the # special form");
                 return false;
             }
-        ;}
+        }
+#line 1566 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 13:
-
-/* Line 1455 of yacc.c  */
-#line 311 "ce_expr.yy"
+#line 311 "ce_expr.yy" /* yacc.c:1646  */
     {
-            (yyval.rval_ptr) = build_constant_array<dods_byte, Byte>((yyvsp[(5) - (6)].byte_values), DDS(arg));
-        ;}
+            (yyval.rval_ptr) = build_constant_array<dods_byte, Byte>((yyvsp[-1].byte_values), DDS(arg));
+        }
+#line 1574 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 14:
-
-/* Line 1455 of yacc.c  */
-#line 317 "ce_expr.yy"
+#line 317 "ce_expr.yy" /* yacc.c:1646  */
     {
-            (yyval.rval_ptr) = build_constant_array<dods_int16, Int16>((yyvsp[(5) - (6)].int16_values), DDS(arg));
-        ;}
+            (yyval.rval_ptr) = build_constant_array<dods_int16, Int16>((yyvsp[-1].int16_values), DDS(arg));
+        }
+#line 1582 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 15:
-
-/* Line 1455 of yacc.c  */
-#line 323 "ce_expr.yy"
+#line 323 "ce_expr.yy" /* yacc.c:1646  */
     {
-            (yyval.rval_ptr) = build_constant_array<dods_uint16, UInt16>((yyvsp[(5) - (6)].uint16_values), DDS(arg));
-        ;}
+            (yyval.rval_ptr) = build_constant_array<dods_uint16, UInt16>((yyvsp[-1].uint16_values), DDS(arg));
+        }
+#line 1590 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 16:
-
-/* Line 1455 of yacc.c  */
-#line 329 "ce_expr.yy"
+#line 329 "ce_expr.yy" /* yacc.c:1646  */
     {
-            (yyval.rval_ptr) = build_constant_array<dods_int32, Int32>((yyvsp[(5) - (6)].int32_values), DDS(arg));
-        ;}
+            (yyval.rval_ptr) = build_constant_array<dods_int32, Int32>((yyvsp[-1].int32_values), DDS(arg));
+        }
+#line 1598 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 17:
-
-/* Line 1455 of yacc.c  */
-#line 335 "ce_expr.yy"
+#line 335 "ce_expr.yy" /* yacc.c:1646  */
     {
-            (yyval.rval_ptr) = build_constant_array<dods_uint32, UInt32>((yyvsp[(5) - (6)].uint32_values), DDS(arg));
-        ;}
+            (yyval.rval_ptr) = build_constant_array<dods_uint32, UInt32>((yyvsp[-1].uint32_values), DDS(arg));
+        }
+#line 1606 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 18:
-
-/* Line 1455 of yacc.c  */
-#line 341 "ce_expr.yy"
+#line 341 "ce_expr.yy" /* yacc.c:1646  */
     {
-            (yyval.rval_ptr) = build_constant_array<dods_float32, Float32>((yyvsp[(5) - (6)].float32_values), DDS(arg));
-        ;}
+            (yyval.rval_ptr) = build_constant_array<dods_float32, Float32>((yyvsp[-1].float32_values), DDS(arg));
+        }
+#line 1614 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 19:
-
-/* Line 1455 of yacc.c  */
-#line 347 "ce_expr.yy"
+#line 347 "ce_expr.yy" /* yacc.c:1646  */
     {
-            (yyval.rval_ptr) = build_constant_array<dods_float64, Float64>((yyvsp[(5) - (6)].float64_values), DDS(arg));
-        ;}
+            (yyval.rval_ptr) = build_constant_array<dods_float64, Float64>((yyvsp[-1].float64_values), DDS(arg));
+        }
+#line 1622 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 20:
-
-/* Line 1455 of yacc.c  */
-#line 356 "ce_expr.yy"
+#line 356 "ce_expr.yy" /* yacc.c:1646  */
     {
-              if (!check_int32((yyvsp[(1) - (1)].id)))
+              if (!check_int32((yyvsp[0].id)))
                   throw Error(malformed_expr, "#<type>(hint, value, ...) special form expected hint to be an integer");
                    
-              arg_length_hint_value = atoi((yyvsp[(1) - (1)].id));
+              arg_length_hint_value = atoi((yyvsp[0].id));
               (yyval.boolean) = true;
-          ;}
+          }
+#line 1634 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 21:
-
-/* Line 1455 of yacc.c  */
-#line 367 "ce_expr.yy"
+#line 367 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.byte_values) = make_fast_arg_list<byte_arg_list, dods_byte>(arg_length_hint_value, (yyvsp[(1) - (1)].byte_value));
-          ;}
+              (yyval.byte_values) = make_fast_arg_list<byte_arg_list, dods_byte>(arg_length_hint_value, (yyvsp[0].byte_value));
+          }
+#line 1642 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 22:
-
-/* Line 1455 of yacc.c  */
-#line 371 "ce_expr.yy"
+#line 371 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.byte_values) = make_fast_arg_list<byte_arg_list, dods_byte>((yyvsp[(1) - (3)].byte_values), (yyvsp[(3) - (3)].byte_value));
-          ;}
+              (yyval.byte_values) = make_fast_arg_list<byte_arg_list, dods_byte>((yyvsp[-2].byte_values), (yyvsp[0].byte_value));
+          }
+#line 1650 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 23:
-
-/* Line 1455 of yacc.c  */
-#line 378 "ce_expr.yy"
+#line 378 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.byte_value) = strtol((yyvsp[(1) - (1)].id), 0, 0);
-          ;}
+              (yyval.byte_value) = strtol((yyvsp[0].id), 0, 0);
+          }
+#line 1658 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 24:
-
-/* Line 1455 of yacc.c  */
-#line 385 "ce_expr.yy"
+#line 385 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.int16_values) = make_fast_arg_list<int16_arg_list, dods_int16>(arg_length_hint_value, (yyvsp[(1) - (1)].int16_value));
-          ;}
+              (yyval.int16_values) = make_fast_arg_list<int16_arg_list, dods_int16>(arg_length_hint_value, (yyvsp[0].int16_value));
+          }
+#line 1666 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 25:
-
-/* Line 1455 of yacc.c  */
-#line 389 "ce_expr.yy"
+#line 389 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.int16_values) = make_fast_arg_list<int16_arg_list, dods_int16>((yyvsp[(1) - (3)].int16_values), (yyvsp[(3) - (3)].int16_value));
-          ;}
+              (yyval.int16_values) = make_fast_arg_list<int16_arg_list, dods_int16>((yyvsp[-2].int16_values), (yyvsp[0].int16_value));
+          }
+#line 1674 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 26:
-
-/* Line 1455 of yacc.c  */
-#line 396 "ce_expr.yy"
+#line 396 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.int16_value) = strtol((yyvsp[(1) - (1)].id), 0, 0);
-          ;}
+              (yyval.int16_value) = strtol((yyvsp[0].id), 0, 0);
+          }
+#line 1682 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 27:
-
-/* Line 1455 of yacc.c  */
-#line 403 "ce_expr.yy"
+#line 403 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.uint16_values) = make_fast_arg_list<uint16_arg_list, dods_uint16>(arg_length_hint_value, (yyvsp[(1) - (1)].uint16_value));
-          ;}
+              (yyval.uint16_values) = make_fast_arg_list<uint16_arg_list, dods_uint16>(arg_length_hint_value, (yyvsp[0].uint16_value));
+          }
+#line 1690 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 28:
-
-/* Line 1455 of yacc.c  */
-#line 407 "ce_expr.yy"
+#line 407 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.uint16_values) = make_fast_arg_list<uint16_arg_list, dods_uint16>((yyvsp[(1) - (3)].uint16_values), (yyvsp[(3) - (3)].uint16_value));
-          ;}
+              (yyval.uint16_values) = make_fast_arg_list<uint16_arg_list, dods_uint16>((yyvsp[-2].uint16_values), (yyvsp[0].uint16_value));
+          }
+#line 1698 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 29:
-
-/* Line 1455 of yacc.c  */
-#line 414 "ce_expr.yy"
+#line 414 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.uint16_value) = strtoul((yyvsp[(1) - (1)].id), 0, 0);
-          ;}
+              (yyval.uint16_value) = strtoul((yyvsp[0].id), 0, 0);
+          }
+#line 1706 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 30:
-
-/* Line 1455 of yacc.c  */
-#line 421 "ce_expr.yy"
+#line 421 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.int32_values) = make_fast_arg_list<int32_arg_list, dods_int32>(arg_length_hint_value, (yyvsp[(1) - (1)].int32_value));
-          ;}
+              (yyval.int32_values) = make_fast_arg_list<int32_arg_list, dods_int32>(arg_length_hint_value, (yyvsp[0].int32_value));
+          }
+#line 1714 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 31:
-
-/* Line 1455 of yacc.c  */
-#line 425 "ce_expr.yy"
+#line 425 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.int32_values) = make_fast_arg_list<int32_arg_list, dods_int32>((yyvsp[(1) - (3)].int32_values), (yyvsp[(3) - (3)].int32_value));
-          ;}
+              (yyval.int32_values) = make_fast_arg_list<int32_arg_list, dods_int32>((yyvsp[-2].int32_values), (yyvsp[0].int32_value));
+          }
+#line 1722 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 32:
-
-/* Line 1455 of yacc.c  */
-#line 432 "ce_expr.yy"
+#line 432 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.int32_value) = strtol((yyvsp[(1) - (1)].id), 0, 0);
-          ;}
+              (yyval.int32_value) = strtol((yyvsp[0].id), 0, 0);
+          }
+#line 1730 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 33:
-
-/* Line 1455 of yacc.c  */
-#line 439 "ce_expr.yy"
+#line 439 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.uint32_values) = make_fast_arg_list<uint32_arg_list, dods_uint32>(arg_length_hint_value, (yyvsp[(1) - (1)].uint32_value));
-          ;}
+              (yyval.uint32_values) = make_fast_arg_list<uint32_arg_list, dods_uint32>(arg_length_hint_value, (yyvsp[0].uint32_value));
+          }
+#line 1738 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 34:
-
-/* Line 1455 of yacc.c  */
-#line 443 "ce_expr.yy"
+#line 443 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.uint32_values) = make_fast_arg_list<uint32_arg_list, dods_uint32>((yyvsp[(1) - (3)].uint32_values), (yyvsp[(3) - (3)].uint32_value));
-          ;}
+              (yyval.uint32_values) = make_fast_arg_list<uint32_arg_list, dods_uint32>((yyvsp[-2].uint32_values), (yyvsp[0].uint32_value));
+          }
+#line 1746 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 35:
-
-/* Line 1455 of yacc.c  */
-#line 450 "ce_expr.yy"
+#line 450 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.uint32_value) = strtoul((yyvsp[(1) - (1)].id), 0, 0);
-          ;}
+              (yyval.uint32_value) = strtoul((yyvsp[0].id), 0, 0);
+          }
+#line 1754 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 36:
-
-/* Line 1455 of yacc.c  */
-#line 457 "ce_expr.yy"
+#line 457 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.float32_values) = make_fast_arg_list<float32_arg_list, dods_float32>(arg_length_hint_value, (yyvsp[(1) - (1)].float32_value));
-          ;}
+              (yyval.float32_values) = make_fast_arg_list<float32_arg_list, dods_float32>(arg_length_hint_value, (yyvsp[0].float32_value));
+          }
+#line 1762 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 37:
-
-/* Line 1455 of yacc.c  */
-#line 461 "ce_expr.yy"
+#line 461 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.float32_values) = make_fast_arg_list<float32_arg_list, dods_float32>((yyvsp[(1) - (3)].float32_values), (yyvsp[(3) - (3)].float32_value));
-          ;}
+              (yyval.float32_values) = make_fast_arg_list<float32_arg_list, dods_float32>((yyvsp[-2].float32_values), (yyvsp[0].float32_value));
+          }
+#line 1770 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 38:
-
-/* Line 1455 of yacc.c  */
-#line 468 "ce_expr.yy"
+#line 468 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.float32_value) = strtof((yyvsp[(1) - (1)].id), 0);
-          ;}
+              (yyval.float32_value) = strtof((yyvsp[0].id), 0);
+          }
+#line 1778 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 39:
-
-/* Line 1455 of yacc.c  */
-#line 475 "ce_expr.yy"
+#line 475 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.float64_values) = make_fast_arg_list<float64_arg_list, dods_float64>(arg_length_hint_value, (yyvsp[(1) - (1)].float64_value));
-          ;}
+              (yyval.float64_values) = make_fast_arg_list<float64_arg_list, dods_float64>(arg_length_hint_value, (yyvsp[0].float64_value));
+          }
+#line 1786 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 40:
-
-/* Line 1455 of yacc.c  */
-#line 479 "ce_expr.yy"
+#line 479 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.float64_values) = make_fast_arg_list<float64_arg_list, dods_float64>((yyvsp[(1) - (3)].float64_values), (yyvsp[(3) - (3)].float64_value));
-          ;}
+              (yyval.float64_values) = make_fast_arg_list<float64_arg_list, dods_float64>((yyvsp[-2].float64_values), (yyvsp[0].float64_value));
+          }
+#line 1794 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 41:
-
-/* Line 1455 of yacc.c  */
-#line 486 "ce_expr.yy"
+#line 486 "ce_expr.yy" /* yacc.c:1646  */
     {
-              (yyval.float64_value) = strtod((yyvsp[(1) - (1)].id), 0);
-          ;}
+              (yyval.float64_value) = strtod((yyvsp[0].id), 0);
+          }
+#line 1802 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 42:
-
-/* Line 1455 of yacc.c  */
-#line 493 "ce_expr.yy"
+#line 493 "ce_expr.yy" /* yacc.c:1646  */
     {
 		    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));
+		    if ((f = get_btp_function(*(EVALUATOR(arg)), (yyvsp[-3].id)))) {
+			    EVALUATOR(arg)->append_clause(f, (yyvsp[-1].r_val_l_ptr));
 			    (yyval.boolean) = true;
 		    }
-		    else if ((p_f = get_proj_function(*(EVALUATOR(arg)), (yyvsp[(1) - (4)].id)))) { 
+		    else if ((p_f = get_proj_function(*(EVALUATOR(arg)), (yyvsp[-3].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)));
+			    BaseType **args = build_btp_args( (yyvsp[-1].r_val_l_ptr), dds );
+			    (*p_f)(((yyvsp[-1].r_val_l_ptr)) ? (yyvsp[-1].r_val_l_ptr)->size():0, args, dds, *(EVALUATOR(arg)));
 			    delete[] args;
 			    (yyval.boolean) = true;
 		    }
 		    else {
-			    no_such_func(arg, (yyvsp[(1) - (4)].id));
+			    no_such_func(arg, (yyvsp[-3].id));
 		    }
-		;}
+		}
+#line 1826 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 44:
-
-/* Line 1455 of yacc.c  */
-#line 516 "ce_expr.yy"
+#line 516 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    (yyval.boolean) = (yyvsp[(1) - (3)].boolean) && (yyvsp[(3) - (3)].boolean);
-		;}
+		    (yyval.boolean) = (yyvsp[-2].boolean) && (yyvsp[0].boolean);
+		}
+#line 1834 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 45:
-
-/* Line 1455 of yacc.c  */
-#line 522 "ce_expr.yy"
+#line 522 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    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));
+		    if ((yyvsp[-4].rval_ptr)) {
+			EVALUATOR(arg)->append_clause((yyvsp[-3].op), (yyvsp[-4].rval_ptr), (yyvsp[-1].r_val_l_ptr));
 			(yyval.boolean) = true;
 		    }
 		    else
 			(yyval.boolean) = false;
-		;}
+		}
+#line 1847 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 46:
-
-/* Line 1455 of yacc.c  */
-#line 531 "ce_expr.yy"
+#line 531 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    if ((yyvsp[(1) - (3)].rval_ptr)) {
+		    if ((yyvsp[-2].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);
+			rv->push_back((yyvsp[0].rval_ptr));
+			EVALUATOR(arg)->append_clause((yyvsp[-1].op), (yyvsp[-2].rval_ptr), rv);
 			(yyval.boolean) = true;
 		    }
 		    else
 			(yyval.boolean) = false;
-		;}
+		}
+#line 1862 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 47:
-
-/* Line 1455 of yacc.c  */
-#line 542 "ce_expr.yy"
+#line 542 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    (yyval.boolean) = (yyvsp[(1) - (1)].boolean);
-		;}
+		    (yyval.boolean) = (yyvsp[0].boolean);
+		}
+#line 1870 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 48:
-
-/* Line 1455 of yacc.c  */
-#line 549 "ce_expr.yy"
+#line 549 "ce_expr.yy" /* yacc.c:1646  */
     {
-		   bool_func b_func = get_function((*EVALUATOR(arg)), (yyvsp[(1) - (4)].id));
+		   bool_func b_func = get_function((*EVALUATOR(arg)), (yyvsp[-3].id));
 		   if (!b_func) {
-		       no_such_func(arg, (yyvsp[(1) - (4)].id));
+		       no_such_func(arg, (yyvsp[-3].id));
 		   }
 		   else {
-		       EVALUATOR(arg)->append_clause(b_func, (yyvsp[(3) - (4)].r_val_l_ptr));
+		       EVALUATOR(arg)->append_clause(b_func, (yyvsp[-1].r_val_l_ptr));
 		       (yyval.boolean) = true;
 		   }
-	       ;}
+	       }
+#line 1885 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 50:
-
-/* Line 1455 of yacc.c  */
-#line 564 "ce_expr.yy"
+#line 564 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    btp_func func = get_btp_function((*EVALUATOR(arg)), (yyvsp[(1) - (4)].id));
+		    btp_func func = get_btp_function((*EVALUATOR(arg)), (yyvsp[-3].id));
 		    if (func) {
-			    (yyval.rval_ptr) = new rvalue(func, (yyvsp[(3) - (4)].r_val_l_ptr));
+			    (yyval.rval_ptr) = new rvalue(func, (yyvsp[-1].r_val_l_ptr));
 		    } 
 		    else { 
-			    no_such_func(arg, (yyvsp[(1) - (4)].id));
+			    no_such_func(arg, (yyvsp[-3].id));
 		    }
-		;}
+		}
+#line 1899 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 51:
-
-/* Line 1455 of yacc.c  */
-#line 574 "ce_expr.yy"
+#line 574 "ce_expr.yy" /* yacc.c:1646  */
     {
-            (yyval.rval_ptr) = (yyvsp[(1) - (1)].rval_ptr);
-        ;}
+            (yyval.rval_ptr) = (yyvsp[0].rval_ptr);
+        }
+#line 1907 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 52:
-
-/* Line 1455 of yacc.c  */
-#line 580 "ce_expr.yy"
+#line 578 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    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;
-		;}
+            (yyval.rval_ptr) = (yyvsp[0].rval_ptr);
+        }
+#line 1915 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 53:
-
-/* Line 1455 of yacc.c  */
-#line 587 "ce_expr.yy"
+#line 584 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    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));
+		    if ((yyvsp[0].rval_ptr))
+			    (yyval.r_val_l_ptr) = make_rvalue_list((yyvsp[0].rval_ptr));
 		    else
 			    (yyval.r_val_l_ptr) = 0;
-		;}
+		}
+#line 1926 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 54:
-
-/* Line 1455 of yacc.c  */
-#line 596 "ce_expr.yy"
-    {  
-		      (yyval.r_val_l_ptr) = (yyvsp[(1) - (1)].r_val_l_ptr);
-	      ;}
+#line 591 "ce_expr.yy" /* yacc.c:1646  */
+    {
+		    if ((yyvsp[-2].r_val_l_ptr) && (yyvsp[0].rval_ptr))
+			    (yyval.r_val_l_ptr) = append_rvalue_list((yyvsp[-2].r_val_l_ptr), (yyvsp[0].rval_ptr));
+		    else
+			    (yyval.r_val_l_ptr) = 0;
+		}
+#line 1937 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
   case 55:
+#line 600 "ce_expr.yy" /* yacc.c:1646  */
+    {  
+		      (yyval.r_val_l_ptr) = (yyvsp[0].r_val_l_ptr);
+	      }
+#line 1945 "ce_expr.tab.cc" /* yacc.c:1646  */
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 600 "ce_expr.yy"
+  case 56:
+#line 604 "ce_expr.yy" /* yacc.c:1646  */
     { 
 		      (yyval.r_val_l_ptr) = 0; 
-	      ;}
+	      }
+#line 1953 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 56:
-
-/* Line 1455 of yacc.c  */
-#line 606 "ce_expr.yy"
+  case 57:
+#line 610 "ce_expr.yy" /* yacc.c:1646  */
     { 
-		    BaseType *btp = DDS(arg)->var(www2id((yyvsp[(1) - (1)].id)));
+		    BaseType *btp = DDS(arg)->var(www2id((yyvsp[0].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))) {
+			    string name_tmp;
+			    if (check_int32((yyvsp[0].id))) {
 			        new_val.type = dods_int32_c;
-			        new_val.v.i = atoi((yyvsp[(1) - (1)].id));
+			        new_val.v.i = atoi((yyvsp[0].id));
 			    }
-			    else if (check_uint32((yyvsp[(1) - (1)].id))) {
+			    else if (check_uint32((yyvsp[0].id))) {
 			        new_val.type = dods_uint32_c;
-			        new_val.v.ui = atoi((yyvsp[(1) - (1)].id));
+			        new_val.v.ui = atoi((yyvsp[0].id));
 			    }
-			    else if (check_float64((yyvsp[(1) - (1)].id))) {
+			    else if (check_float64((yyvsp[0].id))) {
 			        new_val.type = dods_float64_c;
-			        new_val.v.f = atof((yyvsp[(1) - (1)].id));
+			        new_val.v.f = atof((yyvsp[0].id));
 			    }
 			    else {
 			        new_val.type = dods_str_c;
-			        new_val.v.s = new string(www2id((yyvsp[(1) - (1)].id)));
+				// The 'new' here was used because www2id() modifies the
+				// std::string arg in place but 'value' holds a string*.
+			        // new_val.v.s = new string(www2id($1));
+				// I replcaed this with a local tmp to avoid the dynamic
+				// allocation and the need to call delete. This was part of
+				// the fix for ticket 2240. jhrg 7/30/14
+				name_tmp = (yyvsp[0].id);
+				name_tmp = www2id(name_tmp);
+				new_val.v.s = &name_tmp;
 			    }
 			    BaseType *btp = make_variable((*EVALUATOR(arg)), new_val);
 			    (yyval.rval_ptr) = new rvalue(btp);
 		    }
-		;}
+		}
+#line 1995 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 57:
-
-/* Line 1455 of yacc.c  */
-#line 635 "ce_expr.yy"
+  case 58:
+#line 648 "ce_expr.yy" /* yacc.c:1646  */
     {
-                    if ((yyvsp[(1) - (1)].val).type != dods_str_c || (yyvsp[(1) - (1)].val).v.s == 0 || (yyvsp[(1) - (1)].val).v.s->empty())
+                    if ((yyvsp[0].val).type != dods_str_c || (yyvsp[0].val).v.s == 0 || (yyvsp[0].val).v.s->empty())
                         ce_exprerror(arg, "Malformed string", "");
                         
-                    BaseType *var = DDS(arg)->var(www2id(*((yyvsp[(1) - (1)].val).v.s)));
+                    BaseType *var = DDS(arg)->var(www2id(*((yyvsp[0].val).v.s)));
                     if (var) {
                         (yyval.rval_ptr) = new rvalue(var);
                     }
                     else {
-                        var = make_variable((*EVALUATOR(arg)), (yyvsp[(1) - (1)].val)); 
+                        var = make_variable((*EVALUATOR(arg)), (yyvsp[0].val)); 
                         (yyval.rval_ptr) = new rvalue(var);
                     }
-                ;}
+		    // When the scanner (ce_expr.lex) returns the SCAN_STR token type
+		    // it makes a local copy of the string in a new std::string object
+		    // that we must delete. Fix for a bug report by Aron.Bartle at mechdyne.com
+		    // See ticket 2240. jhrg 7/30/14
+		    delete (yyvsp[0].val).v.s;
+                }
+#line 2018 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 58:
-
-/* Line 1455 of yacc.c  */
-#line 651 "ce_expr.yy"
+  case 59:
+#line 672 "ce_expr.yy" /* yacc.c:1646  */
     {
-                    (yyval.boolean) = (*DDS(arg)).mark((yyvsp[(1) - (1)].id), true);
-                ;}
+                    if (!bracket_projection((*DDS(arg)), (yyvsp[-1].id), (yyvsp[0].int_ll_ptr)))
+                      no_such_ident(arg, (yyvsp[-1].id), "array, grid or sequence");
+                    
+                    // strncpy($$, $1, ID_MAX-1);
+                    // $$[ID_MAX-1] = '\0';
+
+                    DDS(arg)->mark((yyvsp[-1].id), true);
+                    (yyval.rval_ptr) = new rvalue(DDS(arg)->var((yyvsp[-1].id)));
+                }
+#line 2033 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 59:
+  case 60:
+#line 685 "ce_expr.yy" /* yacc.c:1646  */
+    {
+                    (yyval.boolean) = (*DDS(arg)).mark((yyvsp[0].id), true);
+                }
+#line 2041 "ce_expr.tab.cc" /* yacc.c:1646  */
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 656 "ce_expr.yy"
+  case 61:
+#line 691 "ce_expr.yy" /* yacc.c:1646  */
     {
                     //string name = www2id($1);
-                    if (!bracket_projection((*DDS(arg)), (yyvsp[(1) - (2)].id), (yyvsp[(2) - (2)].int_ll_ptr)))
-                      no_such_ident(arg, (yyvsp[(1) - (2)].id), "array, grid or sequence");
+                    if (!bracket_projection((*DDS(arg)), (yyvsp[-1].id), (yyvsp[0].int_ll_ptr)))
+                      no_such_ident(arg, (yyvsp[-1].id), "array, grid or sequence");
                     
-                    strncpy((yyval.id), (yyvsp[(1) - (2)].id), ID_MAX-1);
+                    strncpy((yyval.id), (yyvsp[-1].id), ID_MAX-1);
                     (yyval.id)[ID_MAX-1] = '\0';
-                ;}
+                }
+#line 2054 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 60:
-
-/* Line 1455 of yacc.c  */
-#line 665 "ce_expr.yy"
+  case 62:
+#line 700 "ce_expr.yy" /* yacc.c:1646  */
     {
-                    string name = string((yyvsp[(1) - (2)].id)) + string((yyvsp[(2) - (2)].id));
+                    string name = string((yyvsp[-1].id)) + string((yyvsp[0].id));
                     strncpy((yyval.id), name.c_str(), ID_MAX-1);
                     (yyval.id)[ID_MAX-1] = '\0';
-                ;}
+                }
+#line 2064 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 61:
-
-/* Line 1455 of yacc.c  */
-#line 671 "ce_expr.yy"
+  case 63:
+#line 706 "ce_expr.yy" /* yacc.c:1646  */
     {
-                    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)))
+                    string name = string((yyvsp[-2].id)) + string((yyvsp[-1].id));
+                    if (!bracket_projection((*DDS(arg)), name.c_str(), (yyvsp[0].int_ll_ptr)))
                       no_such_ident(arg, name.c_str(), "array, grid or sequence");
 
                     strncpy((yyval.id), name.c_str(), ID_MAX-1);
                     (yyval.id)[ID_MAX-1] = '\0';
-                ;}
+                }
+#line 2077 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 62:
-
-/* Line 1455 of yacc.c  */
-#line 682 "ce_expr.yy"
+  case 64:
+#line 717 "ce_expr.yy" /* yacc.c:1646  */
     { 
-                    strncpy((yyval.id), www2id((yyvsp[(1) - (1)].id)).c_str(), ID_MAX-1);
+                    strncpy((yyval.id), www2id((yyvsp[0].id)).c_str(), ID_MAX-1);
                     (yyval.id)[ID_MAX-1] = '\0';
-                ;}
+                }
+#line 2086 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 63:
-
-/* Line 1455 of yacc.c  */
-#line 687 "ce_expr.yy"
+  case 65:
+#line 722 "ce_expr.yy" /* yacc.c:1646  */
     {
-                    if ((yyvsp[(1) - (1)].val).type != dods_str_c || (yyvsp[(1) - (1)].val).v.s == 0 || (yyvsp[(1) - (1)].val).v.s->empty())
+                    if ((yyvsp[0].val).type != dods_str_c || (yyvsp[0].val).v.s == 0 || (yyvsp[0].val).v.s->empty())
                         ce_exprerror(arg, "Malformed string", "");
                         
-                    strncpy((yyval.id), www2id(*((yyvsp[(1) - (1)].val).v.s)).c_str(), ID_MAX-1);
-                    
+                    strncpy((yyval.id), www2id(*((yyvsp[0].val).v.s)).c_str(), ID_MAX-1);
+		    // See comment about regarding the scanner's behavior WRT SCAN_STR.
+		    // jhrg 7/30/14
+                    delete (yyvsp[0].val).v.s;
+
                     (yyval.id)[ID_MAX-1] = '\0';
-                ;}
+                }
+#line 2102 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 64:
-
-/* Line 1455 of yacc.c  */
-#line 698 "ce_expr.yy"
+  case 66:
+#line 736 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    (yyval.int_ll_ptr) = make_array_indices((yyvsp[(1) - (1)].int_l_ptr));
-		;}
+		    (yyval.int_ll_ptr) = make_array_indices((yyvsp[0].int_l_ptr));
+		}
+#line 2110 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 65:
-
-/* Line 1455 of yacc.c  */
-#line 702 "ce_expr.yy"
+  case 67:
+#line 740 "ce_expr.yy" /* yacc.c:1646  */
     {
-		    (yyval.int_ll_ptr) = append_array_index((yyvsp[(1) - (2)].int_ll_ptr), (yyvsp[(2) - (2)].int_l_ptr));
-		;}
+		    (yyval.int_ll_ptr) = append_array_index((yyvsp[-1].int_ll_ptr), (yyvsp[0].int_l_ptr));
+		}
+#line 2118 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 66:
-
-/* Line 1455 of yacc.c  */
-#line 714 "ce_expr.yy"
+  case 68:
+#line 754 "ce_expr.yy" /* yacc.c:1646  */
     {
-    if (!check_uint32((yyvsp[(2) - (3)].id)))
-        throw Error(malformed_expr, "The word `" + string((yyvsp[(2) - (3)].id)) + "' is not a valid array index.");
+    if (!check_uint32((yyvsp[-1].id)))
+        throw Error(malformed_expr, "The word `" + string((yyvsp[-1].id)) + "' is not a valid array index.");
     value i;
     i.type = dods_uint32_c;
-    i.v.i = atoi((yyvsp[(2) - (3)].id));
+    i.v.i = atoi((yyvsp[-1].id));
     (yyval.int_l_ptr) = make_array_index(i);
-;}
+}
+#line 2131 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 67:
-
-/* Line 1455 of yacc.c  */
-#line 723 "ce_expr.yy"
+  case 69:
+#line 763 "ce_expr.yy" /* yacc.c:1646  */
     {
     value i;
     i.type = dods_int32_c;
     i.v.i =-1;
     (yyval.int_l_ptr) = make_array_index(i);
-;}
+}
+#line 2142 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 68:
-
-/* Line 1455 of yacc.c  */
-#line 730 "ce_expr.yy"
+  case 70:
+#line 770 "ce_expr.yy" /* yacc.c:1646  */
     {
-    if (!check_uint32((yyvsp[(2) - (5)].id)))
-        throw Error(malformed_expr, "The word `" + string((yyvsp[(2) - (5)].id)) + "' is not a valid array index.");
-    if (!check_uint32((yyvsp[(4) - (5)].id)))
-        throw Error(malformed_expr, "The word `" + string((yyvsp[(4) - (5)].id)) + "' is not a valid array index.");
+    if (!check_uint32((yyvsp[-3].id)))
+        throw Error(malformed_expr, "The word `" + string((yyvsp[-3].id)) + "' is not a valid array index.");
+    if (!check_uint32((yyvsp[-1].id)))
+        throw Error(malformed_expr, "The word `" + string((yyvsp[-1].id)) + "' is not a valid array index.");
     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));
+    i.v.i = atoi((yyvsp[-3].id));
+    j.v.i = atoi((yyvsp[-1].id));
     (yyval.int_l_ptr) = make_array_index(i, j);
-;}
+}
+#line 2158 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 69:
-
-/* Line 1455 of yacc.c  */
-#line 742 "ce_expr.yy"
+  case 71:
+#line 782 "ce_expr.yy" /* yacc.c:1646  */
     {
-    if (!check_uint32((yyvsp[(2) - (5)].id)))
-        throw Error(malformed_expr, "The word `" + string((yyvsp[(2) - (5)].id)) + "' is not a valid array index.");
+    if (!check_uint32((yyvsp[-3].id)))
+        throw Error(malformed_expr, "The word `" + string((yyvsp[-3].id)) + "' is not a valid array index.");
     value i,j;
     i.type = dods_uint32_c;
     j.type = dods_int32_c;  /* signed */
-    i.v.i = atoi((yyvsp[(2) - (5)].id));
+    i.v.i = atoi((yyvsp[-3].id));
     j.v.i = -1;
     (yyval.int_l_ptr) = make_array_index(i, j);
-;}
+}
+#line 2173 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 70:
-
-/* Line 1455 of yacc.c  */
-#line 753 "ce_expr.yy"
+  case 72:
+#line 793 "ce_expr.yy" /* yacc.c:1646  */
     {
-    if (!check_uint32((yyvsp[(2) - (7)].id)))
-        throw Error(malformed_expr, "The word `" + string((yyvsp[(2) - (7)].id)) + "' is not a valid array index.");
-    if (!check_uint32((yyvsp[(4) - (7)].id)))
-        throw Error(malformed_expr, "The word `" + string((yyvsp[(4) - (7)].id)) + "' is not a valid array index.");
-    if (!check_uint32((yyvsp[(6) - (7)].id)))
-        throw Error(malformed_expr, "The word `" + string((yyvsp[(6) - (7)].id)) + "' is not a valid array index.");
+    if (!check_uint32((yyvsp[-5].id)))
+        throw Error(malformed_expr, "The word `" + string((yyvsp[-5].id)) + "' is not a valid array index.");
+    if (!check_uint32((yyvsp[-3].id)))
+        throw Error(malformed_expr, "The word `" + string((yyvsp[-3].id)) + "' is not a valid array index.");
+    if (!check_uint32((yyvsp[-1].id)))
+        throw Error(malformed_expr, "The word `" + string((yyvsp[-1].id)) + "' is not a valid array index.");
     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));
+    i.v.i = atoi((yyvsp[-5].id));
+    j.v.i = atoi((yyvsp[-3].id));
+    k.v.i = atoi((yyvsp[-1].id));
     (yyval.int_l_ptr) = make_array_index(i, j, k);
-;}
+}
+#line 2192 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
-  case 71:
-
-/* Line 1455 of yacc.c  */
-#line 768 "ce_expr.yy"
+  case 73:
+#line 808 "ce_expr.yy" /* yacc.c:1646  */
     {
-    if (!check_uint32((yyvsp[(2) - (7)].id)))
-        throw Error(malformed_expr, "The word `" + string((yyvsp[(2) - (7)].id)) + "' is not a valid array index.");
-    if (!check_uint32((yyvsp[(4) - (7)].id)))
-        throw Error(malformed_expr, "The word `" + string((yyvsp[(4) - (7)].id)) + "' is not a valid array index.");
+    if (!check_uint32((yyvsp[-5].id)))
+        throw Error(malformed_expr, "The word `" + string((yyvsp[-5].id)) + "' is not a valid array index.");
+    if (!check_uint32((yyvsp[-3].id)))
+        throw Error(malformed_expr, "The word `" + string((yyvsp[-3].id)) + "' is not a valid array index.");
     value i, j, k;
     i.type = j.type = dods_uint32_c;
     k.type = dods_int32_c;
-    i.v.i = atoi((yyvsp[(2) - (7)].id));
-    j.v.i = atoi((yyvsp[(4) - (7)].id));
+    i.v.i = atoi((yyvsp[-5].id));
+    j.v.i = atoi((yyvsp[-3].id));
     k.v.i = -1;
     (yyval.int_l_ptr) = make_array_index(i, j, k);
-;}
+}
+#line 2210 "ce_expr.tab.cc" /* yacc.c:1646  */
     break;
 
 
-
-/* Line 1455 of yacc.c  */
-#line 2395 "ce_expr.tab.cc"
+#line 2214 "ce_expr.tab.cc" /* yacc.c:1646  */
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -2402,7 +2232,7 @@ yyreduce:
 
   *++yyvsp = yyval;
 
-  /* Now `shift' the result of the reduction.  Determine what state
+  /* 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.  */
 
@@ -2417,10 +2247,14 @@ yyreduce:
   goto yynewstate;
 
 
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
+/*--------------------------------------.
+| yyerrlab -- here on detecting error.  |
+`--------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -2428,37 +2262,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (arg, YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-	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 (arg, yymsg);
-	  }
-	else
-	  {
-	    yyerror (arg, YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (arg, yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -2467,20 +2300,20 @@ yyerrlab:
   if (yyerrstatus == 3)
     {
       /* If just tried and failed to reuse lookahead token after an
-	 error, discard it.  */
+         error, discard it.  */
 
       if (yychar <= YYEOF)
-	{
-	  /* Return failure if at end of input.  */
-	  if (yychar == YYEOF)
-	    YYABORT;
-	}
+        {
+          /* Return failure if at end of input.  */
+          if (yychar == YYEOF)
+            YYABORT;
+        }
       else
-	{
-	  yydestruct ("Error: discarding",
-		      yytoken, &yylval, arg);
-	  yychar = YYEMPTY;
-	}
+        {
+          yydestruct ("Error: discarding",
+                      yytoken, &yylval, arg);
+          yychar = YYEMPTY;
+        }
     }
 
   /* Else will try to reuse lookahead token after shifting the error
@@ -2499,7 +2332,7 @@ yyerrorlab:
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-  /* Do not reclaim the symbols of the rule which action triggered
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
   yylen = 0;
@@ -2512,35 +2345,37 @@ yyerrorlab:
 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
 `-------------------------------------------------------------*/
 yyerrlab1:
-  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+  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;
-	    }
-	}
+      if (!yypact_value_is_default (yyn))
+        {
+          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;
+        YYABORT;
 
 
       yydestruct ("Error: popping",
-		  yystos[yystate], yyvsp, arg);
+                  yystos[yystate], yyvsp, arg);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
     }
 
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -2564,7 +2399,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -2576,16 +2411,21 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval, arg);
-  /* Do not reclaim the symbols of the rule which action triggered
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval, arg);
+    }
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
   YY_STACK_PRINT (yyss, yyssp);
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-		  yystos[*yyssp], yyvsp, arg);
+                  yystos[*yyssp], yyvsp, arg);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
@@ -2596,14 +2436,9 @@ yyreturn:
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
 #endif
-  /* Make sure YYID is used.  */
-  return YYID (yyresult);
+  return yyresult;
 }
-
-
-
-/* Line 1675 of yacc.c  */
-#line 792 "ce_expr.yy"
+#line 832 "ce_expr.yy" /* yacc.c:1906  */
 
 
 // All these error reporting function now throw instances of Error. The expr
@@ -2666,9 +2501,7 @@ 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;
 
@@ -3159,4 +2992,3 @@ rvalue *build_constant_array(vector<t> *values, DDS *dds)
     return new rvalue(array);
 }
 
-
diff --git a/ce_expr.tab.hh b/ce_expr.tab.hh
index 3bbb2a2..96a3de3 100644
--- a/ce_expr.tab.hh
+++ b/ce_expr.tab.hh
@@ -1,21 +1,19 @@
+/* A Bison parser, made by GNU Bison 3.0.1.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* Bison interface for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
 
-/* 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 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 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/>.  */
 
@@ -28,14 +26,21 @@
    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.  */
 
+#ifndef YY_CE_EXPR_CE_EXPR_TAB_HH_INCLUDED
+# define YY_CE_EXPR_CE_EXPR_TAB_HH_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int ce_exprdebug;
+#endif
 /* "%code requires" blocks.  */
-
-/* Line 1676 of yacc.c  */
-#line 41 "ce_expr.yy"
+#line 41 "ce_expr.yy" /* yacc.c:1909  */
 
 
 #include "config.h"
@@ -131,45 +136,39 @@ template<class t, class T>
 rvalue *build_constant_array(vector<t> *values, DDS *dds);
 
 
+#line 140 "ce_expr.tab.hh" /* yacc.c:1909  */
 
-
-/* Line 1676 of yacc.c  */
-#line 138 "ce_expr.tab.hh"
-
-/* Tokens.  */
+/* Token type.  */
 #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,
-     SCAN_STAR = 267,
-     SCAN_HASH_BYTE = 268,
-     SCAN_HASH_INT16 = 269,
-     SCAN_HASH_UINT16 = 270,
-     SCAN_HASH_INT32 = 271,
-     SCAN_HASH_UINT32 = 272,
-     SCAN_HASH_FLOAT32 = 273,
-     SCAN_HASH_FLOAT64 = 274
-   };
+  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,
+    SCAN_STAR = 267,
+    SCAN_HASH_BYTE = 268,
+    SCAN_HASH_INT16 = 269,
+    SCAN_HASH_UINT16 = 270,
+    SCAN_HASH_INT32 = 271,
+    SCAN_HASH_UINT32 = 272,
+    SCAN_HASH_FLOAT32 = 273,
+    SCAN_HASH_FLOAT64 = 274
+  };
 #endif
 
-
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
 {
-
-/* Line 1676 of yacc.c  */
-#line 145 "ce_expr.yy"
+#line 145 "ce_expr.yy" /* yacc.c:1909  */
 
     bool boolean;
     int op;
@@ -202,16 +201,15 @@ typedef union YYSTYPE
     libdap::rvalue *rval_ptr;
     libdap::rvalue_list *r_val_l_ptr;
 
-
-
-/* Line 1676 of yacc.c  */
-#line 209 "ce_expr.tab.hh"
-} YYSTYPE;
+#line 205 "ce_expr.tab.hh" /* yacc.c:1909  */
+};
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
+
 extern YYSTYPE ce_exprlval;
 
+int ce_exprparse (ce_parser_arg *arg);
 
+#endif /* !YY_CE_EXPR_CE_EXPR_TAB_HH_INCLUDED  */
diff --git a/ce_expr.yy b/ce_expr.yy
index 92f48f5..90abc55 100644
--- a/ce_expr.yy
+++ b/ce_expr.yy
@@ -205,7 +205,7 @@ rvalue *build_constant_array(vector<t> *values, DDS *dds);
 %type <int_l_ptr> array_index
 %type <int_ll_ptr> array_indices
 
-%type <rval_ptr> r_value id_or_const array_const_special_form
+%type <rval_ptr> r_value id_or_const array_const_special_form array_projection_rvalue
 %type <r_val_l_ptr> r_value_list arg_list
 
 %type <byte_value> fast_byte_arg
@@ -574,6 +574,10 @@ r_value: id_or_const
         {
             $$ = $1;
         }
+        | array_projection_rvalue
+        {
+            $$ = $1;
+        }
 ;
 
 r_value_list:	r_value
@@ -611,6 +615,7 @@ id_or_const: SCAN_WORD
 		    }
 		    else {
 			    value new_val;
+			    string name_tmp;
 			    if (check_int32($1)) {
 			        new_val.type = dods_int32_c;
 			        new_val.v.i = atoi($1);
@@ -625,7 +630,15 @@ id_or_const: SCAN_WORD
 			    }
 			    else {
 			        new_val.type = dods_str_c;
-			        new_val.v.s = new string(www2id($1));
+				// The 'new' here was used because www2id() modifies the
+				// std::string arg in place but 'value' holds a string*.
+			        // new_val.v.s = new string(www2id($1));
+				// I replcaed this with a local tmp to avoid the dynamic
+				// allocation and the need to call delete. This was part of
+				// the fix for ticket 2240. jhrg 7/30/14
+				name_tmp = $1;
+				name_tmp = www2id(name_tmp);
+				new_val.v.s = &name_tmp;
 			    }
 			    BaseType *btp = make_variable((*EVALUATOR(arg)), new_val);
 			    $$ = new rvalue(btp);
@@ -644,6 +657,27 @@ id_or_const: SCAN_WORD
                         var = make_variable((*EVALUATOR(arg)), $1); 
                         $$ = new rvalue(var);
                     }
+		    // When the scanner (ce_expr.lex) returns the SCAN_STR token type
+		    // it makes a local copy of the string in a new std::string object
+		    // that we must delete. Fix for a bug report by Aron.Bartle at mechdyne.com
+		    // See ticket 2240. jhrg 7/30/14
+		    delete $1.v.s;
+                }
+;
+
+/* this must return an rvalue. It should run bracket_projection() 
+   and then return the BaseType of the Array wrapped in a RValue
+   object. */
+array_projection_rvalue : name array_indices
+                {
+                    if (!bracket_projection((*DDS(arg)), $1, $2))
+                      no_such_ident(arg, $1, "array, grid or sequence");
+                    
+                    // strncpy($$, $1, ID_MAX-1);
+                    // $$[ID_MAX-1] = '\0';
+
+                    DDS(arg)->mark($1, true);
+                    $$ = new rvalue(DDS(arg)->var($1));
                 }
 ;
 
@@ -651,6 +685,7 @@ array_projection : array_proj_clause
                 {
                     $$ = (*DDS(arg)).mark($1, true);
                 }
+;
                 
 array_proj_clause: name array_indices
                 {
@@ -689,7 +724,10 @@ name:           SCAN_WORD
                         ce_exprerror(arg, "Malformed string", "");
                         
                     strncpy($$, www2id(*($1.v.s)).c_str(), ID_MAX-1);
-                    
+		    // See comment about regarding the scanner's behavior WRT SCAN_STR.
+		    // jhrg 7/30/14
+                    delete $1.v.s;
+
                     $$[ID_MAX-1] = '\0';
                 }
 ;
@@ -710,7 +748,9 @@ array_indices:  array_index
  * from n to the end with a stride of m. To encode this with as little 
  * disruption as possible, we represent the star with -1. jhrg 12/20/12
  */ 
-array_index:    '[' SCAN_WORD ']'
+array_index:
+
+'[' SCAN_WORD ']'
 {
     if (!check_uint32($2))
         throw Error(malformed_expr, "The word `" + string($2) + "' is not a valid array index.");
@@ -851,9 +891,7 @@ 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;
 
diff --git a/chunked_istream.cc b/chunked_istream.cc
new file mode 100644
index 0000000..b559fe6
--- /dev/null
+++ b/chunked_istream.cc
@@ -0,0 +1,414 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2009 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.
+//
+// Portions of this code were taken verbatim from  Josuttis,
+// "The C++ Standard Library," p.672
+
+#include "config.h"
+
+#include <stdint.h>
+#include <byteswap.h>
+#include <arpa/inet.h>
+
+#include <cstring>
+#include <vector>
+
+#include "chunked_stream.h"
+#include "chunked_istream.h"
+
+#include "Error.h"
+
+//#define DODS_DEBUG
+//#define DODS_DEBUG2
+#ifdef DODS_DEBUG
+#include <iostream>
+#endif
+
+#include "util.h"
+#include "debug.h"
+
+namespace libdap {
+
+/*
+  This code does not use a 'put back' buffer, but here's a picture of the
+  d_buffer pointer, eback(), gptr() and egptr() that can be used to see how
+  the I/O Stream library's streambuf class works. For the case with no
+  putback, just imagine it as zero and eliminate the leftmost extension. This
+  might also come in useful if the code was extended to support put back. I
+  removed that feature because I don't see it being used with our chunked
+  transmission protocol and it requires an extra call to memcopy() when data
+  are added to the internal buffer.
+
+  d_buffer  d_buffer + putBack
+  |         |
+  v         v
+  |---------|--------------------------------------------|....
+  |         |                                            |   .
+  |---------|--------------------------------------------|....
+            ^                         ^                   ^
+            |                         |                   |
+            eback()                   gptr()              egptr()
+
+ */
+
+/**
+ * @brief Insert new characters into the buffer
+ * This specialization of underflow is called when the gptr() is advanced to
+ * the end of the input buffer. At that point it calls the underlying I/O stream
+ * to read the next chunk of data and transfers the data read to the internal
+ * buffer. If an error is found, EOF is returned. If an END chunk with zero
+ * bytes is found, an EOF is returned.
+ * @return The character at the gptr() or EOF
+ */
+std::streambuf::int_type
+chunked_inbuf::underflow()
+{
+    DBG(cerr << "underflow..." << endl);
+    DBG2(cerr << "eback(): " << (void*)eback() << ", gptr(): " << (void*)(gptr()-eback()) << ", egptr(): " << (void*)(egptr()-eback()) << endl);
+
+	// return the next character; uflow() increments the puffer pointer.
+	if (gptr() < egptr())
+		return traits_type::to_int_type(*gptr());
+
+	// gptr() == egptr() so read more data from the underlying input source.
+
+	// To read data from the chunked stream, first read the header
+	uint32_t header;
+	d_is.read((char *) &header, 4);
+#if !BYTE_ORDER_PREFIX
+	// When the endian nature of the server is encoded in the chunk header, the header is
+	// sent using network byte order
+	ntohl(header);
+#endif
+
+	// There are two 'EOF' cases: One where the END chunk is zero bytes and one where
+	// it holds data. In the latter case, bytes those will be read and moved into the
+	// buffer. Once those data are consumed, we'll be back here again and this read()
+	// will return EOF. See below for the other case...
+	if (d_is.eof()) return traits_type::eof();
+#if BYTE_ORDER_PREFIX
+	if (d_twiddle_bytes) header = bswap_32(header);
+#else
+	// (header & CHUNK_LITTLE_ENDIAN) --> is the sender little endian
+	if (!d_set_twiddle) {
+	    d_twiddle_bytes = (is_host_big_endian() == (header & CHUNK_LITTLE_ENDIAN));
+	    d_set_twiddle = true;
+	}
+#endif
+	uint32_t chunk_size = header & CHUNK_SIZE_MASK;
+
+	DBG(cerr << "underflow: chunk size from header: " << chunk_size << endl);
+	DBG(cerr << "underflow: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
+	DBG(cerr << "underflow: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
+
+	// Handle the case where the buffer is not big enough to hold the incoming chunk
+	if (chunk_size > d_buf_size) {
+		d_buf_size = chunk_size;
+		m_buffer_alloc();
+	}
+
+	// If the END chunk has zero bytes, return EOF. See above for more information
+	if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END) return traits_type::eof();
+
+	// Read the chunk's data
+	d_is.read(d_buffer, chunk_size);
+	DBG2(cerr << "underflow: size read: " << d_is.gcount() << ", eof: " << d_is.eof() << ", bad: " << d_is.bad() << endl);
+	if (d_is.bad()) return traits_type::eof();
+
+	DBG2(cerr << "eback(): " << (void*)eback() << ", gptr(): " << (void*)(gptr()-eback()) << ", egptr(): " << (void*)(egptr()-eback()) << endl);
+	setg(d_buffer, 						// beginning of put back area
+			d_buffer,                	// read position (gptr() == eback())
+			d_buffer + chunk_size);  	// end of buffer (egptr()) chunk_size == d_is.gcount() unless there's an error
+
+	DBG2(cerr << "eback(): " << (void*)eback() << ", gptr(): " << (void*)(gptr()-eback()) << ", egptr(): " << (void*)(egptr()-eback()) << endl);
+
+	switch (header & CHUNK_TYPE_MASK) {
+	case CHUNK_END:
+		DBG2(cerr << "Found end chunk" << endl);
+		return traits_type::to_int_type(*gptr());
+	case CHUNK_DATA:
+		return traits_type::to_int_type(*gptr());
+
+	case CHUNK_ERR:
+		// this is pretty much the end of the show... Assume the buffer/chunk holds
+		// the error message text.
+		d_error = true;
+		d_error_message = string(d_buffer, chunk_size);
+		return traits_type::eof();
+	default:
+		d_error = true;
+		d_error_message = "Failed to read known chunk header type.";
+		return traits_type::eof();
+	}
+
+	return traits_type::eof();	// Can never get here; this quiets g++
+}
+
+/**
+ * @brief Read a block of data
+ * This specialization of xsgetn() reads \c num bytes and puts them in \c s
+ * first reading from the internal beffer and then from the stream. Any
+ * characters read from the last chunk that won't fit in to \c s are put
+ * in the buffer, otherwise all data are read directly into \c s, bypassing
+ * the internal buffer (and the extra copy operation that would imply). If
+ * the END chunk is found EOF is not returned and the final read of the
+ * underlying stream is not made; the next call to read(), get(), ..., will
+ * return EOF.
+ * @param s Address of a buffer to hold the data
+ * @param num Number of bytes to read
+ * @return NUmber of bytes actually transferred into \c s. Note that this
+ * number does not include the bytes read from the last chunk that won't
+ * fit into \c s so this will never return a number greater than num.
+ */
+std::streamsize
+chunked_inbuf::xsgetn(char* s, std::streamsize num)
+{
+	DBG(cerr << "xsgetn... num: " << num << endl);
+
+	// if num is <= the chars currently in the buffer
+	if (num <= (egptr() - gptr())) {
+		memcpy(s, gptr(), num);
+		gbump(num);
+
+		return traits_type::not_eof(num);
+	}
+
+	// else they asked for more
+	uint32_t bytes_left_to_read = num;
+
+	// are there any bytes in the buffer? if so grab them first
+	if (gptr() < egptr()) {
+		int bytes_to_transfer = egptr() - gptr();
+		memcpy(s, gptr(), bytes_to_transfer);
+		gbump(bytes_to_transfer);
+		s += bytes_to_transfer;
+		bytes_left_to_read -= bytes_to_transfer;
+	}
+
+	// We need to get more bytes from the underlying stream; at this
+	// point the internal buffer is empty.
+
+	// read the remaining bytes to transfer, a chunk at a time,
+	// and put any leftover stuff in the buffer.
+
+	// note that when the code is here, gptr() == egptr(), so the
+	// next call to read() will fall through the previous tests and
+	// read at least one chunk here.
+	bool done = false;
+    while (!done) {
+        // Get a chunk header
+        uint32_t header;
+        d_is.read((char *) &header, 4);
+#if !BYTE_ORDER_PREFIX
+        ntohl(header);
+#endif
+
+        // There are two EOF cases: One where the END chunk is zero bytes and one where
+        // it holds data. In the latter case, those will be read and moved into the
+        // buffer. Once those data are consumed, we'll be back here again and this read()
+        // will return EOF. See below for the other case...
+        if (d_is.eof()) return traits_type::eof();
+#if BYTE_ORDER_PREFIX
+        if (d_twiddle_bytes) header = bswap_32(header);
+#else
+        // (header & CHUNK_LITTLE_ENDIAN) --> is the sender little endian
+        if (!d_set_twiddle) {
+            d_twiddle_bytes = (is_host_big_endian() == (header & CHUNK_LITTLE_ENDIAN));
+            d_set_twiddle = true;
+        }
+#endif
+
+	    uint32_t chunk_size = header & CHUNK_SIZE_MASK;
+		DBG(cerr << "xsgetn: chunk size from header: " << chunk_size << endl);
+		DBG(cerr << "xsgetn: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
+		DBG(cerr << "xsgetn: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
+
+		// handle error chunks here
+	    if ((header & CHUNK_TYPE_MASK) == CHUNK_ERR) {
+			d_error = true;
+			// Note that d_buffer is not used to avoid calling resize if it is too
+			// small to hold the error message. At this point, there's not much reason
+			// to optimize transport efficiency, however.
+			std::vector<char> message(chunk_size);
+			d_is.read(&message[0], chunk_size);
+			d_error_message = string(&message[0], chunk_size);
+			// leave the buffer and gptr(), ..., in a consistent state (empty)
+			setg(d_buffer, d_buffer, d_buffer);
+	    }
+	    // And zero-length END chunks here.
+	    else if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END) {
+	    	return traits_type::not_eof(num-bytes_left_to_read);
+	    }
+	    // The next case is complicated because we read some data from the current
+	    // chunk into 's' an some into the internal buffer.
+	    else if (chunk_size > bytes_left_to_read) {
+			d_is.read(s, bytes_left_to_read);
+			if (d_is.bad()) return traits_type::eof();
+
+			// Now slurp up the remain part of the chunk and store it in the buffer
+			uint32_t bytes_leftover = chunk_size - bytes_left_to_read;
+			// expand the internal buffer if needed
+		    if (bytes_leftover > d_buf_size) {
+		        d_buf_size = chunk_size;
+		        m_buffer_alloc();
+		    }
+		    // read the remain stuff in to d_buffer
+			d_is.read(d_buffer, bytes_leftover);
+			if (d_is.bad()) return traits_type::eof();
+
+			setg(d_buffer, 										// beginning of put back area
+				 d_buffer,                						// read position (gptr() == eback())
+				 d_buffer + bytes_leftover /*d_is.gcount()*/); 	// end of buffer (egptr())
+
+			bytes_left_to_read = 0 /* -= d_is.gcount()*/;
+		}
+		else {
+			// expand the internal buffer if needed
+		    if (chunk_size > d_buf_size) {
+		        d_buf_size = chunk_size;
+		        m_buffer_alloc();
+		    }
+		    // If we get a chunk that's zero bytes, Don't call read()
+		    // to save the kernel context switch overhead.
+			if (chunk_size > 0) {
+				d_is.read(s, chunk_size);
+				if (d_is.bad()) return traits_type::eof();
+				bytes_left_to_read -= chunk_size /*d_is.gcount()*/;
+				s += chunk_size;
+			}
+		}
+
+	    switch (header & CHUNK_TYPE_MASK) {
+	    case CHUNK_END:
+			DBG(cerr << "Found end chunk" << endl);
+	    	// in this case bytes_left_to_read can be > 0 because we ran out of data
+	    	// before reading all the requested bytes. The next read() call will return
+	    	// eof; this call returns the number of bytes read and transferred to 's'.
+	    	done = true;
+	    	break;
+	    case CHUNK_DATA:
+	    	done = bytes_left_to_read == 0;
+	        break;
+	    case CHUNK_ERR:
+			// this is pretty much the end of the show... The error message has
+	    	// already been read above
+			return traits_type::eof();
+	        break;
+		default:
+			d_error = true;
+			d_error_message = "Failed to read known chunk header type.";
+			return traits_type::eof();
+	    }
+	}
+
+	return traits_type::not_eof(num-bytes_left_to_read);
+}
+
+/**
+ * @brief Read a chunk
+ * Normally the chunked nature of a chunked_istream/chunked_inbuf is
+ * hidden from the caller. This method provides a way to get one chunk
+ * from the stream by forcing its read and returning the size. A subsequent
+ * call to read() for that number of bytes will return all of the data in
+ * the chunk. If there is any data in the chunk_inbuf object's buffer, it is
+ * lost.
+ *
+ * @return The number of bytes read, which is exactly the size of the
+ * next chunk in the stream. Returns EOF on error.
+ */
+std::streambuf::int_type
+chunked_inbuf::read_next_chunk()
+{
+	// To read data from the chunked stream, first read the header
+	uint32_t header;
+	d_is.read((char *) &header, 4);
+#if !BYTE_ORDER_PREFIX
+    ntohl(header);
+#endif
+
+	// There are two 'EOF' cases: One where the END chunk is zero bytes and one where
+	// it holds data. In the latter case, bytes those will be read and moved into the
+	// buffer. Once those data are consumed, we'll be back here again and this read()
+	// will return EOF. See below for the other case...
+	if (d_is.eof()) return traits_type::eof();
+#if BYTE_ORDER_PREFIX
+    if (d_twiddle_bytes) header = bswap_32(header);
+#else
+    // (header & CHUNK_LITTLE_ENDIAN) --> is the sender little endian
+    if (!d_set_twiddle) {
+        d_twiddle_bytes = (is_host_big_endian() == (header & CHUNK_LITTLE_ENDIAN));
+        d_set_twiddle = true;
+    }
+#endif
+
+	uint32_t chunk_size = header & CHUNK_SIZE_MASK;
+
+	DBG(cerr << "read_next_chunk: chunk size from header: " << chunk_size << endl);
+	DBG(cerr << "read_next_chunk: chunk type from header: " << hex << (header & CHUNK_TYPE_MASK) << endl);
+	DBG(cerr << "read_next_chunk: chunk byte order from header: " << hex << (header & CHUNK_BIG_ENDIAN) << endl);
+
+	// Handle the case where the buffer is not big enough to hold the incoming chunk
+	if (chunk_size > d_buf_size) {
+		d_buf_size = chunk_size;
+		m_buffer_alloc();
+	}
+
+	// If the END chunk has zero bytes, return EOF. See above for more information
+	if (chunk_size == 0 && (header & CHUNK_TYPE_MASK) == CHUNK_END) return traits_type::eof();
+
+	// Read the chunk's data
+	d_is.read(d_buffer, chunk_size);
+	DBG2(cerr << "read_next_chunk: size read: " << d_is.gcount() << ", eof: " << d_is.eof() << ", bad: " << d_is.bad() << endl);
+	if (d_is.bad()) return traits_type::eof();
+
+	DBG2(cerr << "eback(): " << (void*)eback() << ", gptr(): " << (void*)(gptr()-eback()) << ", egptr(): " << (void*)(egptr()-eback()) << endl);
+	setg(d_buffer, 						// beginning of put back area
+			d_buffer,                	// read position (gptr() == eback())
+			d_buffer + chunk_size);  	// end of buffer (egptr()) chunk_size == d_is.gcount() unless there's an error
+
+	DBG2(cerr << "eback(): " << (void*)eback() << ", gptr(): " << (void*)(gptr()-eback()) << ", egptr(): " << (void*)(egptr()-eback()) << endl);
+
+	switch (header & CHUNK_TYPE_MASK) {
+	case CHUNK_END:
+		DBG(cerr << "Found end chunk" << endl);
+		return traits_type::not_eof(chunk_size);
+	case CHUNK_DATA:
+		return traits_type::not_eof(chunk_size);
+
+	case CHUNK_ERR:
+		// this is pretty much the end of the show... Assume the buffer/chunk holds
+		// the error message text.
+		d_error = true;
+		d_error_message = string(d_buffer, chunk_size);
+		return traits_type::eof();
+	default:
+		d_error = true;
+		d_error_message = "Failed to read known chunk header type.";
+		return traits_type::eof();
+	}
+
+	return traits_type::eof();	// Can never get here; this quiets g++
+}
+
+}
diff --git a/chunked_istream.h b/chunked_istream.h
new file mode 100644
index 0000000..94c35fb
--- /dev/null
+++ b/chunked_istream.h
@@ -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) 2013 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.
+//
+// Portions of this code were taken verbatim from Josuttis,
+// "The C++ Standard Library," p.672
+
+#ifndef _chunked_istream_h
+#define _chunked_istream_h
+
+#include "chunked_stream.h"
+
+#include <stdint.h>
+
+#include <streambuf>
+#include <istream>
+#include <stdexcept>
+#include <string>
+
+namespace libdap {
+
+class chunked_inbuf: public std::streambuf {
+private:
+	std::istream &d_is;
+
+	uint32_t d_buf_size;	// Size of the data buffer
+	char *d_buffer;			// data buffer
+
+	// In the original implementation of this class, the byte order of the data stream
+	// was passed in via constructors. When BYTE_ORDER_PREFIX is defined that is the
+	// case. However, when it is not defined, the byte order is read from the chunk
+	// header's high order byte (in bit position 2 - see chunked_stream.h). jhrg 11/24/13
+
+	bool d_twiddle_bytes; 	// receiver-makes-right encoding (byte order)...
+	bool d_set_twiddle;
+
+	// If an error chunk is read, save the message here
+	std::string d_error_message;
+	bool d_error;
+
+	/**
+	 * @brief allocate the internal buffer.
+	 * Allocate d_buf_size + putBack characters for the read buffer.
+	 * @param size How much can the buffer hold? Does not include the putBack
+	 * chars.
+	 */
+	void m_buffer_alloc() {
+		delete d_buffer;
+		d_buffer = new char[d_buf_size];
+		setg(d_buffer, 	// beginning of put back area
+			 d_buffer, 	// read position
+		     d_buffer); // end position
+	}
+
+public:
+	/**
+	 * @brief Build a chunked input buffer.
+	 *
+	 * This reads from a chunked stream, extracting an entire chunk and storing it in a
+	 * buffer in one operation. If the chunked_inbuf reads a chunk header that indicates
+	 * the next chunk is going  be bigger than its current buffer size, the object will
+	 * make the buffer larger. This object support 128 characters of 'put back' space. Since
+	 * DAP4 uses receiver makes right, the buffer must be told if it should 'twiddle' the
+	 * header size information. In DAP4 the byte order is sent using a one-byte code _before_
+	 * the chunked transmission starts.
+	 *
+	 * @note In the current implementation, the byte order of the sender is read from the
+	 * first chunk header. The method twiddle_bytes() returns false until the first chunk is
+	 * read, then it returns the correct value. Only the first chunk_header is tested for the
+	 * byte order flag; all subsequent chunks are assumed to use the same byte order.
+	 *
+	 * @param is Use this as a data source
+	 * @param size The size of the input buffer. This should match the likely chunk size.
+	 * If it is smaller than a chunk, it will be resized.
+	 * @param twiddle_bytes Should the header bytes be twiddled? True if this host and the
+	 * send use a different byte-order. The sender's byte order must be sent out-of-band.
+	 */
+#if BYTE_ORDER_PREFIX
+	chunked_inbuf(std::istream &is, int size, bool twiddle_bytes = false)
+        : d_is(is), d_buf_size(size), d_buffer(0), d_twiddle_bytes(twiddle_bytes), d_error(false) {
+		if (d_buf_size & CHUNK_TYPE_MASK)
+			throw std::out_of_range("A chunked_outbuf (or chunked_ostream) was built using a buffer larger than 0x00ffffff");
+
+		m_buffer_alloc();
+	}
+#else
+    chunked_inbuf(std::istream &is, int size)
+        : d_is(is), d_buf_size(size), d_buffer(0), d_twiddle_bytes(false), d_set_twiddle(false), d_error(false) {
+        if (d_buf_size & CHUNK_TYPE_MASK)
+            throw std::out_of_range("A chunked_outbuf (or chunked_ostream) was built using a buffer larger than 0x00ffffff");
+
+        m_buffer_alloc();
+    }
+#endif
+
+	virtual ~chunked_inbuf() {
+		delete d_buffer;
+	}
+
+	int_type read_next_chunk();
+
+	int bytes_in_buffer() const { return (egptr() - gptr()); }
+
+	// d_twiddle_bytes is false initially and is set to the correct value
+	// once the first chunk is read.
+	bool twiddle_bytes() const { return d_twiddle_bytes; }
+
+	bool error() const { return d_error; }
+	std::string error_message() const { return d_error_message; }
+
+protected:
+	virtual int_type underflow();
+
+	virtual std::streamsize xsgetn(char* s, std::streamsize num);
+};
+
+class chunked_istream: public std::istream {
+protected:
+	chunked_inbuf d_cbuf;
+public:
+#if BYTE_ORDER_PREFIX
+	chunked_istream(std::istream &is, int size, bool twiddle_bytes = false) : std::istream(&d_cbuf), d_cbuf(is, size, twiddle_bytes) { }
+#else
+    chunked_istream(std::istream &is, int size) : std::istream(&d_cbuf), d_cbuf(is, size) { }
+#endif
+
+	int read_next_chunk() { return d_cbuf.read_next_chunk(); }
+
+	/**
+	 * How many bytes have been read from the stream and are now in the internal buffer?
+	 * @return Number of buffered bytes.
+	 */
+	int bytes_in_buffer() const { return d_cbuf.bytes_in_buffer(); }
+
+	/**
+	 * Should the receiver twiddle the bytes to match the local machine's byte order?
+	 * Since DAP4 uses 'receiver makes right' encoding, the onus is on the client to
+	 * reorder the bytes if it is, e.g., a big endian machine reading data from a little
+	 * endian server.
+	 *
+	 * @return True if the client (caller) should swap bytes in multi-byte integers, etc.,
+	 * and false if not. This does not directly tell the endian nature of the remote server,
+	 * although that can be inferred.
+	 */
+	bool twiddle_bytes() const { return d_cbuf.twiddle_bytes(); }
+	bool error() const { return d_cbuf.error(); }
+	std::string error_message() const { return d_cbuf.error_message(); }
+};
+
+}
+
+#endif	// _chunked_istream_h
diff --git a/chunked_ostream.cc b/chunked_ostream.cc
new file mode 100644
index 0000000..2cf4211
--- /dev/null
+++ b/chunked_ostream.cc
@@ -0,0 +1,339 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2009 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.
+//
+// Portions of this code were taken verbatim from  Josuttis,
+// "The C++ Standard Library," p.672
+
+#include "config.h"
+
+#include <arpa/inet.h>
+
+#include <stdint.h>
+
+#include <string>
+#include <streambuf>
+
+#include <cstring>
+
+//#define DODS_DEBUG
+
+#include "chunked_stream.h"
+#include "chunked_ostream.h"
+#include "debug.h"
+
+namespace libdap {
+
+// flush the characters in the buffer
+/**
+ * @brief Write out the contents of the buffer as a chunk.
+ *
+ * @return EOF on error, otherwise the number of bytes in the chunk body.
+ */
+std::streambuf::int_type
+chunked_outbuf::data_chunk()
+{
+	DBG(cerr << "In chunked_outbuf::data_chunk" << endl);
+
+	int32_t num = pptr() - pbase();	// num needs to be signed for the call to pbump
+
+	// Since this is called by sync() (e.g., flush()), return 0 and do nothing
+	// when there's no data to send.
+	if (num == 0)
+		return 0;
+
+	// here, write out the chunk headers: CHUNKTYPE and CHUNKSIZE
+	// as a 32-bit unsigned int. Here I assume that num is never
+	// more than 2^24 because that was tested in the constructor
+
+	// Trick: This method always writes CHUNK_DATA type chunks so
+	// the chunk type is always 0x00, and given that num never has
+	// anything bigger than 24-bits, the high order byte is always
+	// 0x00. Of course bit-wise OR with 0x00 isn't going to do
+	// much anyway... Here's the general idea all the same:
+	//
+	// unsigned int chunk_header = (unsigned int)num | CHUNK_type;
+	uint32_t header = num;
+#if !BYTE_ORDER_PREFIX
+	// Add encoding of host's byte order. jhrg 11/24/13
+	if (!d_big_endian) header |= CHUNK_LITTLE_ENDIAN;
+	// network byte order for the header
+	htonl(header);
+#endif
+
+	d_os.write((const char *)&header, sizeof(int32_t));
+
+	// Should bad() throw an error?
+	// Are these functions fast or would the bits be faster?
+	d_os.write(d_buffer, num);
+	if (d_os.eof() || d_os.bad())
+		return traits_type::eof();
+
+	pbump(-num);
+	return num;
+}
+
+/**
+ * @brief Send an end chunk.
+ *
+ * This is like calling flush_chunk(), but it sends a chunk header with a type of
+ * CHUNK_END (instead of CHUNK_DATA). Whatever is in the buffer is written out, but
+ * the stream is can be used to send more chunks.
+ * @note This is called by the chunked_outbuf destructor, so closing a stream using
+ * chunked_outbuf always sends a CHUNK_END type chunk, even if it will have zero
+ * bytes
+ * @return EOF on error, otherwise the number of bytes sent in the chunk.
+ */
+std::streambuf::int_type
+chunked_outbuf::end_chunk()
+{
+	DBG(cerr << "In chunked_outbuf::end_chunk" << endl);
+
+	int32_t num = pptr() - pbase();	// num needs to be signed for the call to pbump
+
+	// write out the chunk headers: CHUNKTYPE and CHUNKSIZE
+	// as a 32-bit unsigned int. Here I assume that num is never
+	// more than 2^24 because that was tested in the constructor
+
+	uint32_t header = (uint32_t)num | CHUNK_END;
+
+#if !BYTE_ORDER_PREFIX
+    // Add encoding of host's byte order. jhrg 11/24/13
+    if (!d_big_endian) header |= CHUNK_LITTLE_ENDIAN;
+    // network byte order for the header
+    htonl(header);
+#endif
+
+    // Write out the CHUNK_END header with the byte count.
+	// This should be called infrequently, so it's probably not worth
+	// optimizing away chunk_header
+	d_os.write((const char *)&header, sizeof(uint32_t));
+
+	// Should bad() throw an error?
+	// Are these functions fast or would the bits be faster?
+	d_os.write(d_buffer, num);
+	if (d_os.eof() || d_os.bad())
+		return traits_type::eof();
+
+	pbump(-num);
+	return num;
+}
+
+/**
+ * @brief Send an error chunk
+ * While building up the next chunk, send an error chunk, ignoring the data currently
+ * write buffer. The buffer is left in a consistent state.
+ * @param msg The error message to include in the error chunk
+ * @return The number of characters ignored.
+ */
+std::streambuf::int_type
+chunked_outbuf::err_chunk(const std::string &m)
+{
+	DBG(cerr << "In chunked_outbuf::err_chunk" << endl);
+	std::string msg = m;
+
+	// Figure out how many chars are in the buffer - these will be
+	// ignored.
+	int32_t num = pptr() - pbase();	// num needs to be signed for the call to pbump
+
+	// write out the chunk headers: CHUNKTYPE and CHUNKSIZE
+	// as a 32-bit unsigned int. Here I assume that num is never
+	// more than 2^24 because that was tested in the constructor
+	if (msg.length() > 0x00FFFFFF)
+		msg = "Error message too long";
+
+	uint32_t header = (uint32_t)msg.length() | CHUNK_ERR;
+
+#if !BYTE_ORDER_PREFIX
+    // Add encoding of host's byte order. jhrg 11/24/13
+    if (!d_big_endian) header |= CHUNK_LITTLE_ENDIAN;
+    // network byte order for the header
+    htonl(header);
+#endif
+
+    // Write out the CHUNK_END header with the byte count.
+	// This should be called infrequently, so it's probably not worth
+	// optimizing away chunk_header
+	d_os.write((const char *)&header, sizeof(uint32_t));
+
+	// Should bad() throw an error?
+	// Are these functions fast or would the bits be faster?
+	d_os.write(msg.data(), msg.length());
+	if (d_os.eof() || d_os.bad())
+		return traits_type::eof();
+
+	// Reset the buffer pointer, effectively ignoring what's in there now
+	pbump(-num);
+
+	// return the number of characters ignored
+	return num;
+}
+
+/**
+ * @brief Virtual method called when the internal buffer would overflow.
+ * When the internal buffer fills, this method is called by the byte that
+ * would cause that overflow. The buffer pointers have been set so that
+ * there is actually space for one more character, so \c c can really be
+ * sent. Put \c c into the buffer and send it, prefixing the buffer
+ * contents with a chunk header.
+ * @note This method is called by the std::ostream code.
+ * @param c The last character to add to the buffer before sending the
+ * next chunk.
+ * @return EOF on error, otherwise the value of \c c.
+ */
+std::streambuf::int_type
+chunked_outbuf::overflow(int c)
+{
+	DBG(cerr << "In chunked_outbuf::overflow" << endl);
+
+	// Note that the buffer and eptr() were set so that when pptr() is
+	// at the end of the buffer, there is actually one more character
+	// available in the buffer.
+	if (!traits_type::eq_int_type(c, traits_type::eof())) {
+		*pptr() = traits_type::not_eof(c);
+		pbump(1);
+	}
+	// flush the buffer
+	if (data_chunk() == traits_type::eof()) {
+		//Error
+		return traits_type::eof();
+	}
+
+	return traits_type::not_eof(c);
+}
+
+/*
+
+  d_buffer
+  |
+  v
+  |--------------------------------------------|....
+  |                                            |   .
+  |--------------------------------------------|....
+  ^                         ^                   ^
+  |                         |                   |
+  pbase()                   pptr()              epptr()
+
+ */
+
+/**
+ * @brief Write bytes to the chunked stream
+ * Write the bytes in \c s to the chunked stream
+ * @param s
+ * @param num
+ * @return The number of bytes written
+ */
+std::streamsize
+chunked_outbuf::xsputn(const char *s, std::streamsize num)
+{
+	DBG(cerr << "In chunked_outbuf::xsputn: num: " << num << endl);
+
+	// if the current block of data will fit in the buffer, put it there.
+	// else, there is at least a complete chunk between what's in the buffer
+	// and what's in 's'; send a chunk header, the stuff in the buffer and
+	// bytes from 's' to make a complete chunk. Then iterate over 's' sending
+	// more chunks until there's less than a complete chunk left in 's'. Put
+	// the bytes remaining 's' in the buffer. Return the number of bytes sent
+	// or 0 if an error is encountered.
+
+	int32_t bytes_in_buffer = pptr() - pbase();	// num needs to be signed for the call to pbump
+
+	// Will num bytes fit in the buffer? The location of epptr() is one back from
+	// the actual end of the buffer, so the next char written will trigger a write
+	// of the buffer as a new data chunk.
+	if (bytes_in_buffer + num < d_buf_size) {
+		DBG2(cerr << ":xsputn: buffering num: " << num << endl);
+		memcpy(pptr(), s, num);
+		pbump(num);
+		return traits_type::not_eof(num);
+	}
+
+	// If here, write a chunk header and a chunk's worth of data by combining the
+	// data in the buffer and some data from 's'.
+	uint32_t header = d_buf_size;
+#if !BYTE_ORDER_PREFIX
+    // Add encoding of host's byte order. jhrg 11/24/13
+    if (!d_big_endian) header |= CHUNK_LITTLE_ENDIAN;
+    // network byte order for the header
+    htonl(header);
+#endif
+	d_os.write((const char *)&header, sizeof(int32_t));	// Data chunk's CHUNK_TYPE is 0x00000000
+
+	// Reset the pptr() and epptr() now in case of an error exit. See the 'if'
+	// at teh end of this for the only code from here down that will modify the
+	// pptr() value.
+	setp(d_buffer, d_buffer + (d_buf_size - 1));
+
+	d_os.write(d_buffer, bytes_in_buffer);
+	if (d_os.eof() || d_os.bad())
+		return traits_type::not_eof(0);
+
+	int bytes_to_fill_out_buffer =  d_buf_size - bytes_in_buffer;
+	d_os.write(s, bytes_to_fill_out_buffer);
+	if (d_os.eof() || d_os.bad())
+		return traits_type::not_eof(0);
+	s += bytes_to_fill_out_buffer;
+	uint32_t bytes_still_to_send = num - bytes_to_fill_out_buffer;
+
+	// Now send all the remaining data in s until the amount remaining doesn't
+	// fill a complete chunk and buffer those data.
+	while (bytes_still_to_send >= d_buf_size) {
+		// This is header for  a chunk of d_buf_size bytes; the size was set above
+		d_os.write((const char *) &header, sizeof(int32_t));
+		d_os.write(s, d_buf_size);
+		if (d_os.eof() || d_os.bad()) return traits_type::not_eof(0);
+		s += d_buf_size;
+		bytes_still_to_send -= d_buf_size;
+	}
+
+	if (bytes_still_to_send > 0) {
+		// if the code is here, one or more chunks have been sent, the
+		// buffer is empty and there are < d_buf_size bytes to send. Buffer
+		// them.
+		memcpy(d_buffer, s, bytes_still_to_send);
+		pbump(bytes_still_to_send);
+	}
+
+	// Unless an error was detected while writing to the stream, the code must
+	// have sent num bytes.
+	return traits_type::not_eof(num);
+}
+
+/**
+ * @brief Synchronize the stream with its data sink.
+ * @note This method is called by flush() among others
+ * @return -1 on error, 0 otherwise.
+ */
+std::streambuf::int_type
+chunked_outbuf::sync()
+{
+	DBG(cerr << "In chunked_outbuf::sync" << endl);
+
+	if (data_chunk() == traits_type::eof()) {
+		// Error
+		return traits_type::not_eof(-1);
+	}
+	return traits_type::not_eof(0);
+}
+
+} // namespace libdap
diff --git a/chunked_ostream.h b/chunked_ostream.h
new file mode 100644
index 0000000..c250fb1
--- /dev/null
+++ b/chunked_ostream.h
@@ -0,0 +1,164 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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.
+//
+// Portions of this code were taken verbatim from  Josuttis,
+// "The C++ Standard Library," p.672
+
+#ifndef _chunkedostream_h
+#define _chunkedostream_h
+
+#include "chunked_stream.h"
+
+#include <streambuf>
+#include <ostream>
+#include <stdexcept>      // std::out_of_range
+
+#include "util.h"
+
+namespace libdap {
+
+class chunked_ostream;
+
+/**
+ * @brief output buffer for a chunked stream
+ * This performs buffered output encoding the data in the stream using
+ * the simple chunking protocol defined for DAP4's binary data transmission.
+ * Each block of data is prefixed by four bytes: A CHUNK TYPE byte followed
+ * by three bytes that are the CHUNK SIZE. There are three CHUNK TYPES:
+ * data, end and error, indicated by the code values 0x00, 0x01 and 0x02.
+ * The size of a chunk is limited to 2^24 data bytes + 4 bytes for the
+ * chunk header.
+ */
+class chunked_outbuf: public std::streambuf {
+	friend class chunked_ostream;
+protected:
+	std::ostream &d_os;			// Write stuff here
+	unsigned int d_buf_size; 	// Size of the data buffer
+	char *d_buffer;				// Data buffer
+	bool d_big_endian;
+
+public:
+	chunked_outbuf(std::ostream &os, unsigned int buf_size) : d_os(os), d_buf_size(buf_size), d_buffer(0) {
+		if (d_buf_size & CHUNK_TYPE_MASK)
+			throw std::out_of_range("A chunked_outbuf (or chunked_ostream) was built using a buffer larger than 0x00ffffff");
+
+		d_big_endian = is_host_big_endian();
+		d_buffer = new char[buf_size];
+		// Trick: making the pointers think the buffer is one char smaller than it
+		// really is ensures that overflow() will be called when there's space for
+		// one more character.
+		setp(d_buffer, d_buffer + (buf_size - 1));
+	}
+
+	virtual ~chunked_outbuf() {
+		// call end_chunk() and not sync()
+		end_chunk();
+
+		delete[] d_buffer;
+	}
+
+protected:
+	// data_chunk and end_chunk might not be needed because they
+	// are called via flush() and ~chunked_outbuf(), resp. jhrg 9/13/13
+	int_type data_chunk();	// sync() and overflow() call this
+	int_type end_chunk();
+
+	int_type err_chunk(const std::string &msg);
+
+	virtual std::streamsize xsputn(const char *s, std::streamsize num);
+	// Manipulate the buffer pointers using pbump() after filling the buffer
+	// and then call data_chunk(). Leave remainder in buffer. Or copy logic
+	// for data_chunk() into loop in this code.
+
+	virtual int_type overflow(int c);
+	virtual int_type sync();
+};
+
+/**
+ * @brief A C++ stream class for chunked data.
+ * This class uses the chunked_outbuf class to provide for chunked
+ * binary serialization of data as specified by DAP4. Information
+ * to be serialized is broken into 'chunks' that are no more than
+ * 2^24 bytes in length. Each chunk is prefixed by a 4 byte header
+ * that indicates the type of chunk and size (number of bytes in the
+ * chunk body). There are three types of chunk: Data; End; and Error.
+ * In normal operation, a DAP4 data document/response is serialized as
+ * a sequence of DATA chunks followed by one END chunk (which may be
+ * zero bytes in length). If, during serialization, an error is detected,
+ * the currently buffered (but not sent) data are discarded and an
+ * ERROR chunk is sent with an error message.
+ *
+ * This class sends the END chunk when its destructor is called.
+ *
+ * Calling flush() on the ostream object will force a DATA chunk to be
+ * sent with the currently buffered data. Normal operation is to wait
+ * for the buffer to fill before sending a DATA chunk.
+ *
+ * @see chunked_outbuf
+ */
+class chunked_ostream: public std::ostream {
+protected:
+	chunked_outbuf d_cbuf;
+public:
+	/**
+	 * Get a chunked_ostream with a buffer.
+	 * @note The buffer size must not be more than 2^24 bytes (0x00ffffff)
+	 * @param buf_size The size of the buffer in bytes.
+	 */
+	chunked_ostream(std::ostream &os, unsigned int buf_size) : std::ostream(&d_cbuf), d_cbuf(os, buf_size) { }
+
+	/**
+	 * @brief Send an end chunk.
+	 * Normally, an end chunk is sent by closing the chunked_ostream, but this
+	 * method can be used to force sending it without closing the stream. Subsequent
+	 * calls to send data will send data chunks.
+	 * @note An end chunk is sent when the stream is closed.
+	 * @return EOF on error or the number of bytes sent in the chunk body.
+	 */
+	int_type write_end_chunk() { return d_cbuf.end_chunk(); }
+
+	/**
+	 * @brief Send the current contents of the buffer as a data chunk.
+	 * Normally, the chunked_ostream object waits until the buffer is full before sending
+	 * the next data chunk. This will force a send with whatever is in the buffer (e.g.,
+	 * the DMR text). Data added after this call will be sent in subsequent chunks.
+	 * @note Calling flush() on the stream forces a data chunk to be sent.
+	 * @return EOF on error, otherwise the number of bytes sent in the chunk body.
+	 */
+	int_type write_data_chunk() { return d_cbuf.data_chunk(); }
+
+	/**
+	 * @brief Send an error message down the stream.
+	 * When called, this method dumps all the data currently in the buffer and
+	 * sends the error message text instead, using a chunk type of CHUNK_ERR. The
+	 * write buffer is maintained, however, so the stream ibject can still be used.
+	 * @param msg The error message text
+	 * @return The number of bytes 'dumped' from the write buffer.
+	 */
+	int_type write_err_chunk(const std::string &msg) { return d_cbuf.err_chunk(msg); }
+};
+
+}
+
+#endif		// _chunkedostream_h
diff --git a/chunked_stream.h b/chunked_stream.h
new file mode 100644
index 0000000..f60e579
--- /dev/null
+++ b/chunked_stream.h
@@ -0,0 +1,29 @@
+/*
+ * chunked_stream.h
+ *
+ *  Created on: Sep 15, 2013
+ *      Author: jimg
+ */
+
+#ifndef CHUNK_STREAM_H_
+#define CHUNK_STREAM_H_
+
+#define CHUNK_DATA 0x00000000
+#define CHUNK_END  0x01000000
+#define CHUNK_ERR  0x02000000
+
+#if !BYTE_ORDER_PREFIX
+// LITTLE or BIG endian if set? jhrg 11/26/13
+// #define CHUNK_BIG_ENDIAN  0x04000000
+
+#define CHUNK_LITTLE_ENDIAN  0x04000000
+#endif
+
+// Chunk type mask masks off the low bytes and the little endian bit.
+// The three chunk types (DATA, END and ERR) are mutually exclusive.
+#define CHUNK_TYPE_MASK 0x03000000
+#define CHUNK_SIZE_MASK 0x00FFFFFF
+
+#define CHUNK_SIZE 4096
+
+#endif /* CHUNK_STREAM_H_ */
diff --git a/conf/._compile b/conf/._compile
new file mode 100755
index 0000000..77b39d4
Binary files /dev/null and b/conf/._compile differ
diff --git a/conf/._config.guess b/conf/._config.guess
new file mode 100755
index 0000000..77b39d4
Binary files /dev/null and b/conf/._config.guess differ
diff --git a/conf/._config.sub b/conf/._config.sub
new file mode 100755
index 0000000..77b39d4
Binary files /dev/null and b/conf/._config.sub differ
diff --git a/conf/._depcomp b/conf/._depcomp
new file mode 100755
index 0000000..77b39d4
Binary files /dev/null and b/conf/._depcomp differ
diff --git a/conf/._install-sh b/conf/._install-sh
new file mode 100755
index 0000000..77b39d4
Binary files /dev/null and b/conf/._install-sh differ
diff --git a/conf/._libtool.m4 b/conf/._libtool.m4
new file mode 100644
index 0000000..be261c0
Binary files /dev/null and b/conf/._libtool.m4 differ
diff --git a/conf/._ltmain.sh b/conf/._ltmain.sh
new file mode 100644
index 0000000..be261c0
Binary files /dev/null and b/conf/._ltmain.sh differ
diff --git a/conf/._ltoptions.m4 b/conf/._ltoptions.m4
new file mode 100644
index 0000000..be261c0
Binary files /dev/null and b/conf/._ltoptions.m4 differ
diff --git a/conf/._ltsugar.m4 b/conf/._ltsugar.m4
new file mode 100644
index 0000000..be261c0
Binary files /dev/null and b/conf/._ltsugar.m4 differ
diff --git a/conf/._ltversion.m4 b/conf/._ltversion.m4
new file mode 100644
index 0000000..be261c0
Binary files /dev/null and b/conf/._ltversion.m4 differ
diff --git a/conf/._lt~obsolete.m4 b/conf/._lt~obsolete.m4
new file mode 100644
index 0000000..be261c0
Binary files /dev/null and b/conf/._lt~obsolete.m4 differ
diff --git a/conf/._missing b/conf/._missing
new file mode 100755
index 0000000..77b39d4
Binary files /dev/null and b/conf/._missing differ
diff --git a/conf/acinclude.m4 b/conf/acinclude.m4
index dfe8197..63a17e7 100644
--- a/conf/acinclude.m4
+++ b/conf/acinclude.m4
@@ -18,7 +18,7 @@
 # 4. Macros for locating various systems (Matlab, etc.)
 # 5. Macros used to test things about the computer/OS/hardware
 #
-# $Id: acinclude.m4 25670 2012-06-29 20:26:48Z jimg $
+# $Id$
 
 # 1. Unidata's macros
 #-------------------------------------------------------------------------
diff --git a/conf/compile b/conf/compile
new file mode 100755
index 0000000..7b4a9a7
--- /dev/null
+++ b/conf/compile
@@ -0,0 +1,342 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-03-05.13; # UTC
+
+# Copyright (C) 1999-2012 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey at cygnus.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, 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.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# 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/config.rpath b/conf/config.rpath
new file mode 100755
index 0000000..c38b914
--- /dev/null
+++ b/conf/config.rpath
@@ -0,0 +1,690 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+#   Copyright 1996-2013 Free Software Foundation, Inc.
+#   Taken from GNU libtool, 2001
+#   Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 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.
+#
+# The first argument passed to this file is the canonical host specification,
+#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+#   than 256 bytes, otherwise the compiler driver will dump core. The only
+#   known workaround is to choose shorter directory names for the build
+#   directory and/or the installation directory.
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+  wl='-Wl,'
+else
+  case "$host_os" in
+    aix*)
+      wl='-Wl,'
+      ;;
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      ;;
+    hpux9* | hpux10* | hpux11*)
+      wl='-Wl,'
+      ;;
+    irix5* | irix6* | nonstopux*)
+      wl='-Wl,'
+      ;;
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+        ecc*)
+          wl='-Wl,'
+          ;;
+        icc* | ifort*)
+          wl='-Wl,'
+          ;;
+        lf95*)
+          wl='-Wl,'
+          ;;
+        nagfor*)
+          wl='-Wl,-Wl,,'
+          ;;
+        pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+          wl='-Wl,'
+          ;;
+        ccc*)
+          wl='-Wl,'
+          ;;
+        xl* | bgxl* | bgf* | mpixl*)
+          wl='-Wl,'
+          ;;
+        como)
+          wl='-lopt='
+          ;;
+        *)
+          case `$CC -V 2>&1 | sed 5q` in
+            *Sun\ F* | *Sun*Fortran*)
+              wl=
+              ;;
+            *Sun\ C*)
+              wl='-Wl,'
+              ;;
+          esac
+          ;;
+      esac
+      ;;
+    newsos6)
+      ;;
+    *nto* | *qnx*)
+      ;;
+    osf3* | osf4* | osf5*)
+      wl='-Wl,'
+      ;;
+    rdos*)
+      ;;
+    solaris*)
+      case $cc_basename in
+        f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+          wl='-Qoption ld '
+          ;;
+        *)
+          wl='-Wl,'
+          ;;
+      esac
+      ;;
+    sunos4*)
+      wl='-Qoption ld '
+      ;;
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      wl='-Wl,'
+      ;;
+    sysv4*MP*)
+      ;;
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      wl='-Wl,'
+      ;;
+    unicos*)
+      wl='-Wl,'
+      ;;
+    uts4*)
+      ;;
+  esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+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
+  # 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.
+  # Unlike libtool, we use -rpath here, not --rpath, since the documented
+  # option of GNU ld is called -rpath, not --rpath.
+  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+  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
+      fi
+      ;;
+    amigaos*)
+      case "$host_cpu" in
+        powerpc)
+          ;;
+        m68k)
+          hardcode_libdir_flag_spec='-L$libdir'
+          hardcode_minus_L=yes
+          ;;
+      esac
+      ;;
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    cygwin* | mingw* | pw32* | cegcc*)
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    haiku*)
+      ;;
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      ;;
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    netbsd*)
+      ;;
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+        ld_shlibs=no
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      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
+          ;;
+        *)
+          if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+            hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+          else
+            ld_shlibs=no
+          fi
+          ;;
+      esac
+      ;;
+    sunos4*)
+      hardcode_direct=yes
+      ;;
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+  esac
+  if test "$ld_shlibs" = no; then
+    hardcode_libdir_flag_spec=
+  fi
+else
+  case "$host_os" in
+    aix3*)
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes; 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
+      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
+            if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+              aix_use_runtimelinking=yes
+              break
+            fi
+          done
+          ;;
+        esac
+      fi
+      hardcode_direct=yes
+      hardcode_libdir_separator=':'
+      if test "$GCC" = yes; then
+        case $host_os in aix4.[012]|aix4.[012].*)
+          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
+            hardcode_minus_L=yes
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_libdir_separator=
+          fi
+          ;;
+        esac
+      fi
+      # Begin _LT_AC_SYS_LIBPATH_AIX.
+      echo 'int main () { return 0; }' > conftest.c
+      ${CC} ${LDFLAGS} conftest.c -o conftest
+      aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+      if test -z "$aix_libpath"; then
+        aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+      fi
+      if test -z "$aix_libpath"; then
+        aix_libpath="/usr/lib:/lib"
+      fi
+      rm -f conftest.c conftest
+      # End _LT_AC_SYS_LIBPATH_AIX.
+      if test "$aix_use_runtimelinking" = yes; then
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+      else
+        if test "$host_cpu" = ia64; then
+          hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+        else
+          hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        fi
+      fi
+      ;;
+    amigaos*)
+      case "$host_cpu" in
+        powerpc)
+          ;;
+        m68k)
+          hardcode_libdir_flag_spec='-L$libdir'
+          hardcode_minus_L=yes
+          ;;
+      esac
+      ;;
+    bsdi[45]*)
+      ;;
+    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=' '
+      libext=lib
+      ;;
+    darwin* | rhapsody*)
+      hardcode_direct=no
+      if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    dgux*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      ;;
+    freebsd2.2*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    freebsd2*)
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      ;;
+    freebsd* | dragonfly*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    hpux9*)
+      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
+      ;;
+    hpux10*)
+      if test "$with_gnu_ld" = no; then
+        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
+      fi
+      ;;
+    hpux11*)
+      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_direct=yes
+            # 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*)
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+    netbsd*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    newsos6)
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+    *nto* | *qnx*)
+      ;;
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+        hardcode_direct=yes
+        if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+        else
+          case "$host_os" in
+            openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+              hardcode_libdir_flag_spec='-R$libdir'
+              ;;
+            *)
+              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
+      ;;
+    osf3*)
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+    osf4* | osf5*)
+      if test "$GCC" = yes; then
+        hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+        # Both cc and cxx compiler support -rpath directly
+        hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      hardcode_libdir_separator=:
+      ;;
+    solaris*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      ;;
+    sunos4*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      ;;
+    sysv4)
+      case $host_vendor in
+        sni)
+          hardcode_direct=yes # is this really true???
+          ;;
+        siemens)
+          hardcode_direct=no
+          ;;
+        motorola)
+          hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+          ;;
+      esac
+      ;;
+    sysv4.3*)
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+        ld_shlibs=yes
+      fi
+      ;;
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      ;;
+    sysv5* | sco3.2v5* | sco5v6*)
+      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator=':'
+      ;;
+    uts4*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      ;;
+    *)
+      ld_shlibs=no
+      ;;
+  esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec=      # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+  aix3*)
+    library_names_spec='$libname.a'
+    ;;
+  aix[4-9]*)
+    library_names_spec='$libname$shrext'
+    ;;
+  amigaos*)
+    case "$host_cpu" in
+      powerpc*)
+        library_names_spec='$libname$shrext' ;;
+      m68k)
+        library_names_spec='$libname.a' ;;
+    esac
+    ;;
+  beos*)
+    library_names_spec='$libname$shrext'
+    ;;
+  bsdi[45]*)
+    library_names_spec='$libname$shrext'
+    ;;
+  cygwin* | mingw* | pw32* | cegcc*)
+    shrext=.dll
+    library_names_spec='$libname.dll.a $libname.lib'
+    ;;
+  darwin* | rhapsody*)
+    shrext=.dylib
+    library_names_spec='$libname$shrext'
+    ;;
+  dgux*)
+    library_names_spec='$libname$shrext'
+    ;;
+  freebsd* | dragonfly*)
+    case "$host_os" in
+      freebsd[123]*)
+        library_names_spec='$libname$shrext$versuffix' ;;
+      *)
+        library_names_spec='$libname$shrext' ;;
+    esac
+    ;;
+  gnu*)
+    library_names_spec='$libname$shrext'
+    ;;
+  haiku*)
+    library_names_spec='$libname$shrext'
+    ;;
+  hpux9* | hpux10* | hpux11*)
+    case $host_cpu in
+      ia64*)
+        shrext=.so
+        ;;
+      hppa*64*)
+        shrext=.sl
+        ;;
+      *)
+        shrext=.sl
+        ;;
+    esac
+    library_names_spec='$libname$shrext'
+    ;;
+  interix[3-9]*)
+    library_names_spec='$libname$shrext'
+    ;;
+  irix5* | irix6* | nonstopux*)
+    library_names_spec='$libname$shrext'
+    case "$host_os" in
+      irix5* | nonstopux*)
+        libsuff= shlibsuff=
+        ;;
+      *)
+        case $LD in
+          *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+          *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+          *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+          *) libsuff= shlibsuff= ;;
+        esac
+        ;;
+    esac
+    ;;
+  linux*oldld* | linux*aout* | linux*coff*)
+    ;;
+  linux* | k*bsd*-gnu | kopensolaris*-gnu)
+    library_names_spec='$libname$shrext'
+    ;;
+  knetbsd*-gnu)
+    library_names_spec='$libname$shrext'
+    ;;
+  netbsd*)
+    library_names_spec='$libname$shrext'
+    ;;
+  newsos6)
+    library_names_spec='$libname$shrext'
+    ;;
+  *nto* | *qnx*)
+    library_names_spec='$libname$shrext'
+    ;;
+  openbsd*)
+    library_names_spec='$libname$shrext$versuffix'
+    ;;
+  os2*)
+    libname_spec='$name'
+    shrext=.dll
+    library_names_spec='$libname.a'
+    ;;
+  osf3* | osf4* | osf5*)
+    library_names_spec='$libname$shrext'
+    ;;
+  rdos*)
+    ;;
+  solaris*)
+    library_names_spec='$libname$shrext'
+    ;;
+  sunos4*)
+    library_names_spec='$libname$shrext$versuffix'
+    ;;
+  sysv4 | sysv4.3*)
+    library_names_spec='$libname$shrext'
+    ;;
+  sysv4*MP*)
+    library_names_spec='$libname$shrext'
+    ;;
+  sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+    library_names_spec='$libname$shrext'
+    ;;
+  tpf*)
+    library_names_spec='$libname$shrext'
+    ;;
+  uts4*)
+    library_names_spec='$libname$shrext'
+    ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
diff --git a/conf/gcov_valgrind.m4 b/conf/gcov_valgrind.m4
new file mode 100644
index 0000000..e1ccbb3
--- /dev/null
+++ b/conf/gcov_valgrind.m4
@@ -0,0 +1,36 @@
+# Support for coverage analysis via gcov:
+# from http://fragglet.livejournal.com/14291.html
+ 
+AC_DEFUN([DODS_GCOV_VALGRIND],
+[
+               
+coverage=no
+AC_ARG_ENABLE(coverage,
+[  --enable-coverage       Enable coverage testing. ],
+[ coverage=yes ])
+              
+if [[ "$coverage" = "yes" ]]; then
+    if [[ "$GCC" = "yes" ]]; then
+        CFLAGS="-fprofile-arcs -ftest-coverage $CFLAGS"
+    else
+        AC_MSG_ERROR([Can only enable coverage when using gcc.])
+    fi
+fi
+               
+# Support for running test cases using valgrind:
+               
+use_valgrind=false
+AC_ARG_ENABLE(valgrind,
+[  --enable-valgrind       Use valgrind when running unit tests. ],
+[ use_valgrind=true ])
+               
+if [[ "$use_valgrind" = "true" ]]; then
+    AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
+             
+    if [[ "$HAVE_VALGRIND" = "no" ]]; then
+        AC_MSG_ERROR([Valgrind not found in PATH. ])
+    fi
+fi
+               
+AM_CONDITIONAL(USE_VALGRIND, $use_valgrind)
+])
\ No newline at end of file
diff --git a/conf/snippet/arg-nonnull.h b/conf/snippet/arg-nonnull.h
index 3a9dd26..8ea2a47 100644
--- a/conf/snippet/arg-nonnull.h
+++ b/conf/snippet/arg-nonnull.h
@@ -1,5 +1,5 @@
 /* A C macro for declaring that specific arguments must not be NULL.
-   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+   Copyright (C) 2009-2013 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
diff --git a/conf/snippet/c++defs.h b/conf/snippet/c++defs.h
index 96da94b..b35b933 100644
--- a/conf/snippet/c++defs.h
+++ b/conf/snippet/c++defs.h
@@ -1,5 +1,5 @@
 /* C++ compatible function declaration macros.
-   Copyright (C) 2010-2012 Free Software Foundation, Inc.
+   Copyright (C) 2010-2013 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
diff --git a/conf/snippet/warn-on-use.h b/conf/snippet/warn-on-use.h
index d4cb94f..1736a1b 100644
--- a/conf/snippet/warn-on-use.h
+++ b/conf/snippet/warn-on-use.h
@@ -1,5 +1,5 @@
 /* A C macro for emitting warnings if a function is used.
-   Copyright (C) 2010-2012 Free Software Foundation, Inc.
+   Copyright (C) 2010-2013 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
@@ -55,7 +55,7 @@
    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; }
+   static char ***rpl_environ (void) { return &environ; }
    _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
    # undef environ
    # define environ (*rpl_environ ())
diff --git a/config.h.in b/config.h.in
index 3ac55a9..ea70a98 100644
--- a/config.h.in
+++ b/config.h.in
@@ -83,13 +83,14 @@
 /* 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 lock shall be considered present. */
+#undef GNULIB_LOCK
+
+/* 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
 
@@ -140,6 +141,10 @@
 /* Define to 1 if you have the `bzero' function. */
 #undef HAVE_BZERO
 
+/* Define to 1 if you have the declaration of `alarm', and to 0 if you don't.
+   */
+#undef HAVE_DECL_ALARM
+
 /* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
    don't. */
 #undef HAVE_DECL_GETC_UNLOCKED
@@ -156,10 +161,6 @@
    don't. */
 #undef HAVE_DECL_MBSINIT
 
-/* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you
-   don't. */
-#undef HAVE_DECL_STRNCASECMP
-
 /* Define to 1 if you have the declaration of `towlower', and to 0 if you
    don't. */
 #undef HAVE_DECL_TOWLOWER
@@ -260,6 +261,12 @@
 /* Define to 1 if you have the `pow' function. */
 #undef HAVE_POW
 
+/* Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE. */
+#undef HAVE_PTHREAD_MUTEX_RECURSIVE
+
+/* Define if the POSIX multithreading library has read/write locks. */
+#undef HAVE_PTHREAD_RWLOCK
+
 /* Define to 1 if you have the `putenv' function. */
 #undef HAVE_PUTENV
 
@@ -312,9 +319,6 @@
 /* Define to 1 if fdatasync is declared even after undefining macros. */
 #undef HAVE_RAW_DECL_FDATASYNC
 
-/* Define to 1 if ffs is declared even after undefining macros. */
-#undef HAVE_RAW_DECL_FFS
-
 /* Define to 1 if fsync is declared even after undefining macros. */
 #undef HAVE_RAW_DECL_FSYNC
 
@@ -459,6 +463,9 @@
 /* Define to 1 if rpmatch is declared even after undefining macros. */
 #undef HAVE_RAW_DECL_RPMATCH
 
+/* Define to 1 if secure_getenv is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_SECURE_GETENV
+
 /* Define to 1 if setenv is declared even after undefining macros. */
 #undef HAVE_RAW_DECL_SETENV
 
@@ -486,12 +493,6 @@
 /* Define to 1 if srandom_r is declared even after undefining macros. */
 #undef HAVE_RAW_DECL_SRANDOM_R
 
-/* Define to 1 if strcasecmp is declared even after undefining macros. */
-#undef HAVE_RAW_DECL_STRCASECMP
-
-/* Define to 1 if strncasecmp is declared even after undefining macros. */
-#undef HAVE_RAW_DECL_STRNCASECMP
-
 /* Define to 1 if strtod is declared even after undefining macros. */
 #undef HAVE_RAW_DECL_STRTOD
 
@@ -657,9 +658,6 @@
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
-
 /* Define to 1 if you have the `strchr' function. */
 #undef HAVE_STRCHR
 
@@ -672,9 +670,6 @@
 /* Define to 1 if you have the <string.h> header file. */
 #undef HAVE_STRING_H
 
-/* Define to 1 if you have the `strncasecmp' function. */
-#undef HAVE_STRNCASECMP
-
 /* Define to 1 if you have the `strtol' function. */
 #undef HAVE_STRTOL
 
@@ -731,6 +726,9 @@
 /* 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 <uuid/uuid.h> header file. */
+#undef HAVE_UUID_UUID_H
+
 /* Define to 1 if you have the <wchar.h> header file. */
 #undef HAVE_WCHAR_H
 
@@ -768,6 +766,9 @@
    */
 #undef LT_OBJDIR
 
+/* If malloc(0) is != NULL, define this to 1. Otherwise define this to 0. */
+#undef MALLOC_0_IS_NONNULL
+
 /* Define if the mbrtowc function has the NULL pwc argument bug. */
 #undef MBRTOWC_NULL_ARG1_BUG
 
@@ -780,9 +781,12 @@
 /* Define if the mbrtowc function returns a wrong return value. */
 #undef MBRTOWC_RETVAL_BUG
 
-/* Remove this to activate assert() calls. */
+/* Define this to suppres assert() calls. */
 #undef NDEBUG
 
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
 /* Name of package */
 #undef PACKAGE
 
@@ -804,6 +808,9 @@
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
+/* Define if the pthread_in_use() detection is hard. */
+#undef PTHREAD_IN_USE_DETECTION_HARD
+
 /* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
    'ptrdiff_t'. */
 #undef PTRDIFF_T_SUFFIX
@@ -866,6 +873,62 @@
 /* Define to 1 if your <sys/time.h> declares `struct tm'. */
 #undef TM_IN_SYS_TIME
 
+/* Define if the POSIX multithreading library can be used. */
+#undef USE_POSIX_THREADS
+
+/* Define if references to the POSIX multithreading library should be made
+   weak. */
+#undef USE_POSIX_THREADS_WEAK
+
+/* Define if the GNU Pth multithreading library can be used. */
+#undef USE_PTH_THREADS
+
+/* Define if references to the GNU Pth multithreading library should be made
+   weak. */
+#undef USE_PTH_THREADS_WEAK
+
+/* Define if the old Solaris multithreading library can be used. */
+#undef USE_SOLARIS_THREADS
+
+/* Define if references to the old Solaris multithreading library should be
+   made weak. */
+#undef USE_SOLARIS_THREADS_WEAK
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable general extensions on OS X.  */
+#ifndef _DARWIN_C_SOURCE
+# undef _DARWIN_C_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 X/Open extensions if necessary.  HP-UX 11.11 defines
+   mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of
+   whether compiling with -Ae or -D_HPUX_SOURCE=1.  */
+#ifndef _XOPEN_SOURCE
+# undef _XOPEN_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define if the native Windows multithreading API can be used. */
+#undef USE_WINDOWS_THREADS
+
 /* Version number of package */
 #undef VERSION
 
@@ -917,6 +980,9 @@
 /* Define to 1 if on MINIX. */
 #undef _MINIX
 
+/* Define to 1 to make NetBSD features available. MINIX 3 needs this. */
+#undef _NETBSD_SOURCE
+
 /* The _Noreturn keyword of C11.  */
 #if ! (defined _Noreturn \
        || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__))
@@ -945,37 +1011,77 @@
 /* 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
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
 
-/* Enable extensions on AIX 3, Interix.  */
-#ifndef _ALL_SOURCE
-# undef _ALL_SOURCE
-#endif
-/* Enable general extensions on Mac OS X.  */
-#ifndef _DARWIN_C_SOURCE
-# undef _DARWIN_C_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
+/* Please see the Gnulib manual for how to use these macros.
+
+   Suppress extern inline with HP-UX cc, as it appears to be broken; see
+   <http://lists.gnu.org/archive/html/bug-texinfo/2013-02/msg00030.html>.
+
+   Suppress extern inline with Sun C in standards-conformance mode, as it
+   mishandles inline functions that call each other.  E.g., for 'inline void f
+   (void) { } inline void g (void) { f (); }', c99 incorrectly complains
+   'reference to static identifier "f" in extern inline function'.
+   This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.
+
+   Suppress the use of extern inline on problematic Apple configurations, as
+   Libc at least through Libc-825.26 (2013-04-09) mishandles it; see, e.g.,
+   <http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html>.
+   Perhaps Apple will fix this some day.  */
+#if (defined __APPLE__ \
+     && ((! defined _DONT_USE_CTYPE_INLINE_ \
+          && (defined __GNUC__ || defined __cplusplus)) \
+         || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \
+             && defined __GNUC__ && ! defined __cplusplus)))
+# define _GL_EXTERN_INLINE_APPLE_BUG
 #endif
-/* Enable extensions on HP NonStop.  */
-#ifndef _TANDEM_SOURCE
-# undef _TANDEM_SOURCE
-#endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
+#if ((__GNUC__ \
+      ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
+      : (199901L <= __STDC_VERSION__ \
+         && !defined __HP_cc \
+         && !(defined __SUNPRO_C && __STDC__))) \
+     && !defined _GL_EXTERN_INLINE_APPLE_BUG)
+# define _GL_INLINE inline
+# define _GL_EXTERN_INLINE extern inline
+# define _GL_EXTERN_INLINE_IN_USE
+#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \
+       && !defined _GL_EXTERN_INLINE_APPLE_BUG)
+# if __GNUC_GNU_INLINE__
+   /* __gnu_inline__ suppresses a GCC 4.2 diagnostic.  */
+#  define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))
+# else
+#  define _GL_INLINE extern inline
+# endif
+# define _GL_EXTERN_INLINE extern
+# define _GL_EXTERN_INLINE_IN_USE
+#else
+# define _GL_INLINE static _GL_UNUSED
+# define _GL_EXTERN_INLINE static _GL_UNUSED
 #endif
 
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
+#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__
+#  define _GL_INLINE_HEADER_CONST_PRAGMA
+# else
+#  define _GL_INLINE_HEADER_CONST_PRAGMA \
+     _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"")
+# endif
+  /* Suppress GCC's bogus "no previous prototype for 'FOO'"
+     and "no previous declaration for 'FOO'"  diagnostics,
+     when FOO is an inline function in the header; see
+     <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113>.  */
+# define _GL_INLINE_HEADER_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \
+    _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \
+    _GL_INLINE_HEADER_CONST_PRAGMA
+# define _GL_INLINE_HEADER_END \
+    _Pragma ("GCC diagnostic pop")
+#else
+# define _GL_INLINE_HEADER_BEGIN
+# define _GL_INLINE_HEADER_END
+#endif
 
 /* 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.  */
@@ -1098,11 +1204,4 @@
    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/configure b/configure
index 4925cf5..5f84860 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libdap 3.12.0.
+# Generated by GNU Autoconf 2.69 for libdap 3.14.0.
 #
 # Report bugs to <opendap-tech at opendap.org>.
 #
@@ -650,8 +650,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='libdap'
 PACKAGE_TARNAME='libdap'
-PACKAGE_VERSION='3.12.0'
-PACKAGE_STRING='libdap 3.12.0'
+PACKAGE_VERSION='3.14.0'
+PACKAGE_STRING='libdap 3.14.0'
 PACKAGE_BUGREPORT='opendap-tech at opendap.org'
 PACKAGE_URL=''
 
@@ -692,6 +692,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
+gl_use_threads_default=
 ac_func_list=
 ac_header_list=
 ac_subst_vars='gltests_LTLIBOBJS
@@ -702,6 +703,9 @@ am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+USE_VALGRIND_FALSE
+USE_VALGRIND_TRUE
+HAVE_VALGRIND
 BUILD_DEVELOPER_FALSE
 BUILD_DEVELOPER_TRUE
 DAP4_DEFINED_FALSE
@@ -768,6 +772,7 @@ REPLACE_ISATTY
 REPLACE_GETPAGESIZE
 REPLACE_GETGROUPS
 REPLACE_GETLOGIN_R
+REPLACE_GETDTABLESIZE
 REPLACE_GETDOMAINNAME
 REPLACE_GETCWD
 REPLACE_FTRUNCATE
@@ -869,13 +874,6 @@ GNULIB_CHDIR
 WINDOWS_64_BIT_OFF_T
 NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H
 NEXT_SYS_TYPES_H
-HAVE_STRINGS_H
-NEXT_AS_FIRST_DIRECTIVE_STRINGS_H
-NEXT_STRINGS_H
-HAVE_DECL_STRNCASECMP
-HAVE_STRCASECMP
-HAVE_FFS
-GNULIB_FFS
 NEXT_AS_FIRST_DIRECTIVE_STDLIB_H
 NEXT_STDLIB_H
 GL_GENERATE_STDINT_H_FALSE
@@ -921,6 +919,7 @@ REPLACE_REALLOC
 REPLACE_RANDOM_R
 REPLACE_PUTENV
 REPLACE_PTSNAME_R
+REPLACE_PTSNAME
 REPLACE_MKSTEMP
 REPLACE_MBTOWC
 REPLACE_MALLOC
@@ -935,6 +934,7 @@ HAVE_STRTOLL
 HAVE_STRTOD
 HAVE_DECL_SETENV
 HAVE_SETENV
+HAVE_SECURE_GETENV
 HAVE_RPMATCH
 HAVE_REALPATH
 HAVE_RANDOM_R
@@ -962,6 +962,7 @@ GNULIB_STRTOULL
 GNULIB_STRTOLL
 GNULIB_STRTOD
 GNULIB_SETENV
+GNULIB_SECURE_GETENV
 GNULIB_RPMATCH
 GNULIB_REALPATH
 GNULIB_REALLOC_POSIX
@@ -985,6 +986,13 @@ GNULIB_CANONICALIZE_FILE_NAME
 GNULIB_CALLOC_POSIX
 GNULIB_ATOLL
 GNULIB__EXIT
+LTLIBMULTITHREAD
+LIBMULTITHREAD
+LTLIBTHREAD
+LIBTHREAD
+LIBPTH_PREFIX
+LTLIBPTH
+LIBPTH
 NEXT_AS_FIRST_DIRECTIVE_LOCALE_H
 NEXT_LOCALE_H
 HAVE_XLOCALE_H
@@ -1022,6 +1030,7 @@ GNULIB_NL_LANGINFO
 LTLIBINTL
 LIBINTL
 pkglibexecdir
+runstatedir
 lispdir
 GL_GENERATE_BYTESWAP_H_FALSE
 GL_GENERATE_BYTESWAP_H_TRUE
@@ -1199,7 +1208,6 @@ build_os
 build_vendor
 build_cpu
 build
-EVAL
 PACKAGE_SUBMINOR_VERSION
 PACKAGE_MINOR_VERSION
 PACKAGE_MAJOR_VERSION
@@ -1270,6 +1278,7 @@ ac_subst_files=''
 ac_user_opts='
 enable_option_checking
 enable_dependency_tracking
+enable_threads
 enable_shared
 enable_static
 with_pic
@@ -1278,6 +1287,8 @@ with_gnu_ld
 with_sysroot
 enable_libtool_lock
 enable_runtime_endian_check
+enable_rpath
+with_libpth_prefix
 with_included_regex
 with_curl
 with_xml2
@@ -1286,6 +1297,8 @@ with_cppunit_exec_prefix
 enable_debug
 enable_dap4
 enable_developer
+enable_coverage
+enable_valgrind
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1845,7 +1858,7 @@ 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.12.0 to adapt to many kinds of systems.
+\`configure' configures libdap 3.14.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1915,7 +1928,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libdap 3.12.0:";;
+     short | recursive ) echo "Configuration of libdap 3.14.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1927,6 +1940,9 @@ Optional Features:
                           do not reject slow dependency extractors
   --disable-dependency-tracking
                           speeds up one-time build
+  --enable-threads={posix|solaris|pth|windows}
+                          specify multithreading API
+  --disable-threads       build without multithread safety
   --enable-shared[=PKGS]  build shared libraries [default=yes]
   --enable-static[=PKGS]  build static libraries [default=yes]
   --enable-fast-install[=PKGS]
@@ -1936,10 +1952,13 @@ Optional Features:
                           Enable runtime tests for big- or little-endian byte
                           order (default is NO)
 
+  --disable-rpath         do not hardcode runtime library paths
   --enable-debug=ARG      Program instrumentation (1,2)
-  --enable-dap4           Enable DAP4 types and responses (default is NO)
+  --enable-dap4           Enable DAP4 types and responses (default is Yes)
   --enable-developer      Build a debug (-g3 -O0) version of this code and
                           include assert() calls in the code (default is no)
+  --enable-coverage       Enable coverage testing.
+  --enable-valgrind       Use valgrind when running unit tests.
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1949,6 +1968,9 @@ Optional Packages:
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-sysroot=DIR Search for dependent libraries within DIR
                         (or the compiler's sysroot if not specified).
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-libpth-prefix[=DIR]  search for libpth in DIR/include and DIR/lib
+  --without-libpth-prefix     don't search for libpth in includedir and libdir
   --without-included-regex
                           don't compile regex; this is the default on systems
                           with recent-enough versions of the GNU C Library
@@ -2042,7 +2064,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libdap configure 3.12.0
+libdap configure 3.14.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2872,7 +2894,7 @@ 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.12.0, which was
+It was created by libdap $as_me 3.14.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3165,7 +3187,6 @@ as_fn_append ac_func_list " iswctype"
 as_fn_append ac_func_list " wcscoll"
 as_fn_append ac_header_list " wchar.h"
 as_fn_append ac_header_list " stdint.h"
-as_fn_append ac_header_list " strings.h"
 as_fn_append ac_header_list " features.h"
 as_fn_append ac_func_list " wcrtomb"
 as_fn_append ac_func_list " iswcntrl"
@@ -3239,7 +3260,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
-$as_echo "#define DAP_PROTOCOL_VERSION \"3.4\"" >>confdefs.h
+$as_echo "#define DAP_PROTOCOL_VERSION \"4.0\"" >>confdefs.h
 
 
 
@@ -3620,7 +3641,6 @@ 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
   [\\/$]* | ?:[\\/]*) ;;
@@ -3731,7 +3751,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libdap'
- VERSION='3.12.0'
+ VERSION='3.14.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3803,9 +3823,6 @@ $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.
@@ -3881,8 +3898,8 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
 
-DAPLIB_CURRENT=16
-DAPLIB_AGE=5
+DAPLIB_CURRENT=18
+DAPLIB_AGE=1
 DAPLIB_REVISION=0
 
 
@@ -3891,8 +3908,8 @@ DAPLIB_REVISION=0
 LIBDAP_VERSION="$DAPLIB_CURRENT:$DAPLIB_REVISION:$DAPLIB_AGE"
 
 
-CLIENTLIB_CURRENT=5
-CLIENTLIB_AGE=2
+CLIENTLIB_CURRENT=7
+CLIENTLIB_AGE=1
 CLIENTLIB_REVISION=0
 
 
@@ -3901,8 +3918,8 @@ CLIENTLIB_REVISION=0
 CLIENTLIB_VERSION="$CLIENTLIB_CURRENT:$CLIENTLIB_REVISION:$CLIENTLIB_AGE"
 
 
-SERVERLIB_CURRENT=12
-SERVERLIB_AGE=5
+SERVERLIB_CURRENT=13
+SERVERLIB_AGE=6
 SERVERLIB_REVISION=0
 
 
@@ -5826,6 +5843,132 @@ fi
   fi
 
 
+if test "x$CC" != xcc; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+		      sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { 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; } &&
+   test -f conftest2.$ac_objext && { { 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
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.$ac_ext >&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_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+      ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+      rm -f conftest2.*
+      if { { 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; } &&
+	 test -f conftest2.$ac_objext && { { 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
+	# cc works too.
+	:
+      else
+	# cc exists but doesn't like -o.
+	eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; 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; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+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 ${ac_cv_header_stdc+:} false; then :
@@ -5956,8 +6099,6 @@ 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" = xyes; then :
   MINIX=yes
@@ -5976,15 +6117,10 @@ $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
+$as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h
 
-      ;;
-  esac
+  fi
 
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
@@ -6027,6 +6163,55 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
 
   $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
 
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5
+$as_echo_n "checking whether _XOPEN_SOURCE should be defined... " >&6; }
+if ${ac_cv_should_define__xopen_source+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_should_define__xopen_source=no
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+          #include <wchar.h>
+          mbstate_t x;
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+             #define _XOPEN_SOURCE 500
+             #include <wchar.h>
+             mbstate_t x;
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_should_define__xopen_source=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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5
+$as_echo "$ac_cv_should_define__xopen_source" >&6; }
+  test $ac_cv_should_define__xopen_source = yes &&
+    $as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h
+
+
 
 
 
@@ -6036,18 +6221,69 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
 
 
 
+
+
+  # Check whether --enable-threads was given.
+if test "${enable_threads+set}" = set; then :
+  enableval=$enable_threads; gl_use_threads=$enableval
+else
+  if test -n "$gl_use_threads_default"; then
+       gl_use_threads="$gl_use_threads_default"
+     else
+       case "$host_os" in
+                                                               osf*) gl_use_threads=no ;;
+         cygwin*)
+               case `uname -r` in
+                 1.[0-5].*) gl_use_threads=no ;;
+                 *)         gl_use_threads=yes ;;
+               esac
+               ;;
+         *)    gl_use_threads=yes ;;
+       esac
+     fi
+
+fi
+
+  if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
+    # For using <pthread.h>:
+    case "$host_os" in
+      osf*)
+        # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
+        # groks <pthread.h>. cc also understands the flag -pthread, but
+        # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
+        # 2. putting a flag into CPPFLAGS that has an effect on the linker
+        # causes the AC_LINK_IFELSE test below to succeed unexpectedly,
+        # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
+        CPPFLAGS="$CPPFLAGS -D_REENTRANT"
+        ;;
+    esac
+    # Some systems optimize for single-threaded programs by default, and
+    # need special flags to disable these optimizations. For example, the
+    # definition of 'errno' in <errno.h>.
+    case "$host_os" in
+      aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;;
+      solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;;
+    esac
+  fi
+
+
+
+
   # Code from module alloca-opt:
   # Code from module btowc:
   # Code from module byteswap:
   # Code from module configmake:
   # Code from module extensions:
 
+  # Code from module extern-inline:
   # Code from module gettext-h:
+  # Code from module havelib:
   # Code from module include_next:
   # Code from module langinfo:
   # Code from module localcharset:
   # Code from module locale:
   # Code from module localeconv:
+  # Code from module lock:
   # Code from module malloc-gnu:
   # Code from module malloc-posix:
   # Code from module mbrtowc:
@@ -6065,10 +6301,12 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
   # Code from module stddef:
   # Code from module stdint:
   # Code from module stdlib:
-  # Code from module strcase:
   # Code from module streq:
-  # Code from module strings:
   # Code from module sys_types:
+  # Code from module threadlib:
+
+
+
   # Code from module unistd:
   # Code from module verify:
   # Code from module wchar:
@@ -16642,6 +16880,33 @@ fi
 
 
 
+bison_version=`bison --version | sed -n '/^bison.*/p' | sed 's at .* \(.*\)@\1@'`
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bison 3.0" >&5
+$as_echo_n "checking for bison 3.0... " >&6; }
+
+# This was used to set a conditional in the d4_ce/Makefile.am to build
+# the DAP4 parsers using bison 3 or get pre-built sources from a set
+# of template files. That didn't work on some linux machines, so bison
+# 3 is a requirement for building until that gets sorted out. jhrg 4/5/15
+
+as_arg_v1="$bison_version"
+as_arg_v2="3.0"
+awk "$as_awk_strverscmp" v1="$as_arg_v1" v2="$as_arg_v2" /dev/null
+case $? in #(
+  1) :
+    as_fn_error $? "not found" "$LINENO" 5 ;; #(
+  0) :
+      ;; #(
+  2) :
+      ;; #(
+  *) :
+     ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found vesion $bison_version" >&5
+$as_echo "found vesion $bison_version" >&6; }
+
 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`
@@ -16954,7 +17219,7 @@ $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
+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 uuid/uuid.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"
@@ -18841,6 +19106,9 @@ $as_echo "$gt_cv_locale_fr" >&6; }
 
 
 
+
+
+
   GNULIB_NL_LANGINFO=0;
     HAVE_NL_LANGINFO=1;
   REPLACE_NL_LANGINFO=0;
@@ -19027,7 +19295,18 @@ main ()
             #if HAVE_SYMLINK
             {
               static char const sym[] = "conftest.sym";
-              if (symlink (".", sym) != 0)
+              if (symlink ("/dev/null", sym) != 0)
+                result |= 2;
+              else
+                {
+                  int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0);
+                  if (fd >= 0)
+                    {
+                      close (fd);
+                      result |= 4;
+                    }
+                }
+              if (unlink (sym) != 0 || symlink (".", sym) != 0)
                 result |= 2;
               else
                 {
@@ -19333,84 +19612,1224 @@ $as_echo "$gl_cv_next_stddef_h" >&6; }
 
 
 
-  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_MBTOWC=0;
-  GNULIB_MKDTEMP=0;
-  GNULIB_MKOSTEMP=0;
-  GNULIB_MKOSTEMPS=0;
-  GNULIB_MKSTEMP=0;
-  GNULIB_MKSTEMPS=0;
-  GNULIB_POSIX_OPENPT=0;
-  GNULIB_PTSNAME=0;
-  GNULIB_PTSNAME_R=0;
-  GNULIB_PUTENV=0;
-  GNULIB_RANDOM=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;
-  GNULIB_WCTOMB=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_POSIX_OPENPT=1;
-  HAVE_PTSNAME=1;
-  HAVE_PTSNAME_R=1;
-  HAVE_RANDOM=1;
-  HAVE_RANDOM_H=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_MBTOWC=0;
-  REPLACE_MKSTEMP=0;
-  REPLACE_PTSNAME_R=0;
-  REPLACE_PUTENV=0;
-  REPLACE_RANDOM_R=0;
-  REPLACE_REALLOC=0;
-  REPLACE_REALPATH=0;
-  REPLACE_SETENV=0;
-  REPLACE_STRTOD=0;
-  REPLACE_UNSETENV=0;
-  REPLACE_WCTOMB=0;
+      if test "X$prefix" = "XNONE"; then
+    acl_final_prefix="$ac_default_prefix"
+  else
+    acl_final_prefix="$prefix"
+  fi
+  if test "X$exec_prefix" = "XNONE"; then
+    acl_final_exec_prefix='${prefix}'
+  else
+    acl_final_exec_prefix="$exec_prefix"
+  fi
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+  prefix="$acl_save_prefix"
 
 
-  { $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 ${gl_cv_func_malloc_posix+:} false; then :
+
+# 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
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+  # contains only /bin. Note that ksh looks also at the FPATH variable,
+  # so we have to set that as well for the test.
+  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
+
+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 ${acl_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$acl_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      acl_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 `"$acl_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="$acl_save_ifs"
+else
+  acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$acl_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 ${acl_cv_prog_gnu_ld+:} false; 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'*)
+  acl_cv_prog_gnu_ld=yes
+  ;;
+*)
+  acl_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5
+$as_echo "$acl_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$acl_cv_prog_gnu_ld
+
+
+
+
+                                                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5
+$as_echo_n "checking for shared library run path origin... " >&6; }
+if ${acl_cv_rpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
+    ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
+    . ./conftest.sh
+    rm -f ./conftest.sh
+    acl_cv_rpath=done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5
+$as_echo "$acl_cv_rpath" >&6; }
+  wl="$acl_cv_wl"
+  acl_libext="$acl_cv_libext"
+  acl_shlibext="$acl_cv_shlibext"
+  acl_libname_spec="$acl_cv_libname_spec"
+  acl_library_names_spec="$acl_cv_library_names_spec"
+  acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+  acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+  acl_hardcode_direct="$acl_cv_hardcode_direct"
+  acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
+    # Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then :
+  enableval=$enable_rpath; :
+else
+  enable_rpath=yes
+fi
+
+
+
+
+  acl_libdirstem=lib
+  acl_libdirstem2=
+  case "$host_os" in
+    solaris*)
+                                    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5
+$as_echo_n "checking for 64-bit host... " >&6; }
+if ${gl_cv_solaris_64bit+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef _LP64
+sixtyfour bits
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "sixtyfour bits" >/dev/null 2>&1; then :
+  gl_cv_solaris_64bit=yes
+else
+  gl_cv_solaris_64bit=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5
+$as_echo "$gl_cv_solaris_64bit" >&6; }
+      if test $gl_cv_solaris_64bit = yes; then
+        acl_libdirstem=lib/64
+        case "$host_cpu" in
+          sparc*)        acl_libdirstem2=lib/sparcv9 ;;
+          i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+        esac
+      fi
+      ;;
+    *)
+      searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+      if test -n "$searchpath"; then
+        acl_save_IFS="${IFS= 	}"; IFS=":"
+        for searchdir in $searchpath; do
+          if test -d "$searchdir"; then
+            case "$searchdir" in
+              */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+              */../ | */.. )
+                # Better ignore directories of this form. They are misleading.
+                ;;
+              *) searchdir=`cd "$searchdir" && pwd`
+                 case "$searchdir" in
+                   */lib64 ) acl_libdirstem=lib64 ;;
+                 esac ;;
+            esac
+          fi
+        done
+        IFS="$acl_save_IFS"
+      fi
+      ;;
+  esac
+  test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+
+
+
+  gl_threads_api=none
+  LIBTHREAD=
+  LTLIBTHREAD=
+  LIBMULTITHREAD=
+  LTLIBMULTITHREAD=
+  if test "$gl_use_threads" != no; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether imported symbols can be declared weak" >&5
+$as_echo_n "checking whether imported symbols can be declared weak... " >&6; }
+if ${gl_cv_have_weak+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gl_cv_have_weak=no
+              cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+extern void xyzzy ();
+#pragma weak xyzzy
+int
+main ()
+{
+xyzzy();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gl_cv_have_weak=maybe
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+       if test $gl_cv_have_weak = maybe; then
+                           if test "$cross_compiling" = yes; then :
+                          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __ELF__
+               Extensible Linking Format
+               #endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "Extensible Linking Format" >/dev/null 2>&1; then :
+  gl_cv_have_weak="guessing yes"
+else
+  gl_cv_have_weak="guessing no"
+fi
+rm -f conftest*
+
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#pragma weak fputs
+int main ()
+{
+  return (fputs == NULL);
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_have_weak=yes
+else
+  gl_cv_have_weak=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_have_weak" >&5
+$as_echo "$gl_cv_have_weak" >&6; }
+    if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
+      # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
+      # it groks <pthread.h>. It's added above, in gl_THREADLIB_EARLY_BODY.
+      ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
+if test "x$ac_cv_header_pthread_h" = xyes; then :
+  gl_have_pthread_h=yes
+else
+  gl_have_pthread_h=no
+fi
+
+
+      if test "$gl_have_pthread_h" = yes; then
+        # Other possible tests:
+        #   -lpthreads (FSU threads, PCthreads)
+        #   -lgthreads
+        gl_have_pthread=
+        # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
+        # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
+        # the second one only in libpthread, and lock.c needs it.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_mutex_lock((pthread_mutex_t*)0);
+               pthread_mutexattr_init((pthread_mutexattr_t*)0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gl_have_pthread=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        # Test for libpthread by looking for pthread_kill. (Not pthread_self,
+        # since it is defined as a macro on OSF/1.)
+        if test -n "$gl_have_pthread"; then
+          # The program links fine without libpthread. But it may actually
+          # need to link with libpthread in order to create multiple threads.
+          { $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 ${ac_cv_lib_pthread_pthread_kill+:} false; 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" = xyes; then :
+  LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
+             # On Solaris and HP-UX, most pthread functions exist also in libc.
+             # Therefore pthread_in_use() needs to actually try to create a
+             # thread: pthread_create from libc will fail, whereas
+             # pthread_create will actually create a thread.
+             case "$host_os" in
+               solaris* | hpux*)
+
+$as_echo "#define PTHREAD_IN_USE_DETECTION_HARD 1" >>confdefs.h
+
+             esac
+
+fi
+
+        else
+          # Some library is needed. Try libpthread and libc_r.
+          { $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 ${ac_cv_lib_pthread_pthread_kill+:} false; 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" = xyes; then :
+  gl_have_pthread=yes
+             LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread
+             LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
+fi
+
+          if test -z "$gl_have_pthread"; then
+            # For FreeBSD 4.
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_kill in -lc_r" >&5
+$as_echo_n "checking for pthread_kill in -lc_r... " >&6; }
+if ${ac_cv_lib_c_r_pthread_kill+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc_r  $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_c_r_pthread_kill=yes
+else
+  ac_cv_lib_c_r_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_c_r_pthread_kill" >&5
+$as_echo "$ac_cv_lib_c_r_pthread_kill" >&6; }
+if test "x$ac_cv_lib_c_r_pthread_kill" = xyes; then :
+  gl_have_pthread=yes
+               LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r
+               LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r
+fi
+
+          fi
+        fi
+        if test -n "$gl_have_pthread"; then
+          gl_threads_api=posix
+
+$as_echo "#define USE_POSIX_THREADS 1" >>confdefs.h
+
+          if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
+            if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+
+$as_echo "#define USE_POSIX_THREADS_WEAK 1" >>confdefs.h
+
+              LIBTHREAD=
+              LTLIBTHREAD=
+            fi
+          fi
+        fi
+      fi
+    fi
+    if test -z "$gl_have_pthread"; then
+      if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then
+        gl_have_solaristhread=
+        gl_save_LIBS="$LIBS"
+        LIBS="$LIBS -lthread"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <thread.h>
+#include <synch.h>
+
+int
+main ()
+{
+thr_self();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gl_have_solaristhread=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        LIBS="$gl_save_LIBS"
+        if test -n "$gl_have_solaristhread"; then
+          gl_threads_api=solaris
+          LIBTHREAD=-lthread
+          LTLIBTHREAD=-lthread
+          LIBMULTITHREAD="$LIBTHREAD"
+          LTLIBMULTITHREAD="$LTLIBTHREAD"
+
+$as_echo "#define USE_SOLARIS_THREADS 1" >>confdefs.h
+
+          if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+
+$as_echo "#define USE_SOLARIS_THREADS_WEAK 1" >>confdefs.h
+
+            LIBTHREAD=
+            LTLIBTHREAD=
+          fi
+        fi
+      fi
+    fi
+    if test "$gl_use_threads" = pth; then
+      gl_save_CPPFLAGS="$CPPFLAGS"
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libpth" >&5
+$as_echo_n "checking how to link with libpth... " >&6; }
+if ${ac_cv_libpth_libs+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+
+
+
+
+
+
+
+    use_additional=yes
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+
+    eval additional_includedir=\"$includedir\"
+    eval additional_libdir=\"$libdir\"
+
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+
+# Check whether --with-libpth-prefix was given.
+if test "${with_libpth_prefix+set}" = set; then :
+  withval=$with_libpth_prefix;
+    if test "X$withval" = "Xno"; then
+      use_additional=no
+    else
+      if test "X$withval" = "X"; then
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+
+          eval additional_includedir=\"$includedir\"
+          eval additional_libdir=\"$libdir\"
+
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+      else
+        additional_includedir="$withval/include"
+        additional_libdir="$withval/$acl_libdirstem"
+        if test "$acl_libdirstem2" != "$acl_libdirstem" \
+           && ! test -d "$withval/$acl_libdirstem"; then
+          additional_libdir="$withval/$acl_libdirstem2"
+        fi
+      fi
+    fi
+
+fi
+
+      LIBPTH=
+  LTLIBPTH=
+  INCPTH=
+  LIBPTH_PREFIX=
+      HAVE_LIBPTH=
+  rpathdirs=
+  ltrpathdirs=
+  names_already_handled=
+  names_next_round='pth '
+  while test -n "$names_next_round"; do
+    names_this_round="$names_next_round"
+    names_next_round=
+    for name in $names_this_round; do
+      already_handled=
+      for n in $names_already_handled; do
+        if test "$n" = "$name"; then
+          already_handled=yes
+          break
+        fi
+      done
+      if test -z "$already_handled"; then
+        names_already_handled="$names_already_handled $name"
+                        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
+        eval value=\"\$HAVE_LIB$uppername\"
+        if test -n "$value"; then
+          if test "$value" = yes; then
+            eval value=\"\$LIB$uppername\"
+            test -z "$value" || LIBPTH="${LIBPTH}${LIBPTH:+ }$value"
+            eval value=\"\$LTLIB$uppername\"
+            test -z "$value" || LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }$value"
+          else
+                                    :
+          fi
+        else
+                              found_dir=
+          found_la=
+          found_so=
+          found_a=
+          eval libname=\"$acl_libname_spec\"    # typically: libname=lib$name
+          if test -n "$acl_shlibext"; then
+            shrext=".$acl_shlibext"             # typically: shrext=.so
+          else
+            shrext=
+          fi
+          if test $use_additional = yes; then
+            dir="$additional_libdir"
+                                    if test -n "$acl_shlibext"; then
+              if test -f "$dir/$libname$shrext"; then
+                found_dir="$dir"
+                found_so="$dir/$libname$shrext"
+              else
+                if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                  ver=`(cd "$dir" && \
+                        for f in "$libname$shrext".*; do echo "$f"; done \
+                        | sed -e "s,^$libname$shrext\\\\.,," \
+                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                        | sed 1q ) 2>/dev/null`
+                  if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                    found_dir="$dir"
+                    found_so="$dir/$libname$shrext.$ver"
+                  fi
+                else
+                  eval library_names=\"$acl_library_names_spec\"
+                  for f in $library_names; do
+                    if test -f "$dir/$f"; then
+                      found_dir="$dir"
+                      found_so="$dir/$f"
+                      break
+                    fi
+                  done
+                fi
+              fi
+            fi
+                        if test "X$found_dir" = "X"; then
+              if test -f "$dir/$libname.$acl_libext"; then
+                found_dir="$dir"
+                found_a="$dir/$libname.$acl_libext"
+              fi
+            fi
+            if test "X$found_dir" != "X"; then
+              if test -f "$dir/$libname.la"; then
+                found_la="$dir/$libname.la"
+              fi
+            fi
+          fi
+          if test "X$found_dir" = "X"; then
+            for x in $LDFLAGS $LTLIBPTH; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+              case "$x" in
+                -L*)
+                  dir=`echo "X$x" | sed -e 's/^X-L//'`
+                                    if test -n "$acl_shlibext"; then
+                    if test -f "$dir/$libname$shrext"; then
+                      found_dir="$dir"
+                      found_so="$dir/$libname$shrext"
+                    else
+                      if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                        ver=`(cd "$dir" && \
+                              for f in "$libname$shrext".*; do echo "$f"; done \
+                              | sed -e "s,^$libname$shrext\\\\.,," \
+                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                              | sed 1q ) 2>/dev/null`
+                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                          found_dir="$dir"
+                          found_so="$dir/$libname$shrext.$ver"
+                        fi
+                      else
+                        eval library_names=\"$acl_library_names_spec\"
+                        for f in $library_names; do
+                          if test -f "$dir/$f"; then
+                            found_dir="$dir"
+                            found_so="$dir/$f"
+                            break
+                          fi
+                        done
+                      fi
+                    fi
+                  fi
+                                    if test "X$found_dir" = "X"; then
+                    if test -f "$dir/$libname.$acl_libext"; then
+                      found_dir="$dir"
+                      found_a="$dir/$libname.$acl_libext"
+                    fi
+                  fi
+                  if test "X$found_dir" != "X"; then
+                    if test -f "$dir/$libname.la"; then
+                      found_la="$dir/$libname.la"
+                    fi
+                  fi
+                  ;;
+              esac
+              if test "X$found_dir" != "X"; then
+                break
+              fi
+            done
+          fi
+          if test "X$found_dir" != "X"; then
+                        LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }-L$found_dir -l$name"
+            if test "X$found_so" != "X"; then
+                                                        if test "$enable_rpath" = no \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem" \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+                                LIBPTH="${LIBPTH}${LIBPTH:+ }$found_so"
+              else
+                                                                                haveit=
+                for x in $ltrpathdirs; do
+                  if test "X$x" = "X$found_dir"; then
+                    haveit=yes
+                    break
+                  fi
+                done
+                if test -z "$haveit"; then
+                  ltrpathdirs="$ltrpathdirs $found_dir"
+                fi
+                                if test "$acl_hardcode_direct" = yes; then
+                                                      LIBPTH="${LIBPTH}${LIBPTH:+ }$found_so"
+                else
+                  if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+                                                            LIBPTH="${LIBPTH}${LIBPTH:+ }$found_so"
+                                                            haveit=
+                    for x in $rpathdirs; do
+                      if test "X$x" = "X$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      rpathdirs="$rpathdirs $found_dir"
+                    fi
+                  else
+                                                                                haveit=
+                    for x in $LDFLAGS $LIBPTH; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                      if test "X$x" = "X-L$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      LIBPTH="${LIBPTH}${LIBPTH:+ }-L$found_dir"
+                    fi
+                    if test "$acl_hardcode_minus_L" != no; then
+                                                                                        LIBPTH="${LIBPTH}${LIBPTH:+ }$found_so"
+                    else
+                                                                                                                                                                                LIBPTH="${LIBPTH}${LIBPTH:+ }-l$name"
+                    fi
+                  fi
+                fi
+              fi
+            else
+              if test "X$found_a" != "X"; then
+                                LIBPTH="${LIBPTH}${LIBPTH:+ }$found_a"
+              else
+                                                LIBPTH="${LIBPTH}${LIBPTH:+ }-L$found_dir -l$name"
+              fi
+            fi
+                        additional_includedir=
+            case "$found_dir" in
+              */$acl_libdirstem | */$acl_libdirstem/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+                if test "$name" = 'pth'; then
+                  LIBPTH_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
+              */$acl_libdirstem2 | */$acl_libdirstem2/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
+                if test "$name" = 'pth'; then
+                  LIBPTH_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
+            esac
+            if test "X$additional_includedir" != "X"; then
+                                                                                                                if test "X$additional_includedir" != "X/usr/include"; then
+                haveit=
+                if test "X$additional_includedir" = "X/usr/local/include"; then
+                  if test -n "$GCC"; then
+                    case $host_os in
+                      linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+                    esac
+                  fi
+                fi
+                if test -z "$haveit"; then
+                  for x in $CPPFLAGS $INCPTH; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                    if test "X$x" = "X-I$additional_includedir"; then
+                      haveit=yes
+                      break
+                    fi
+                  done
+                  if test -z "$haveit"; then
+                    if test -d "$additional_includedir"; then
+                                            INCPTH="${INCPTH}${INCPTH:+ }-I$additional_includedir"
+                    fi
+                  fi
+                fi
+              fi
+            fi
+                        if test -n "$found_la"; then
+                                                        save_libdir="$libdir"
+              case "$found_la" in
+                */* | *\\*) . "$found_la" ;;
+                *) . "./$found_la" ;;
+              esac
+              libdir="$save_libdir"
+                            for dep in $dependency_libs; do
+                case "$dep" in
+                  -L*)
+                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+                                                                                                                                                                if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
+                       && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+                      haveit=
+                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
+                         || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+                        if test -n "$GCC"; then
+                          case $host_os in
+                            linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+                          esac
+                        fi
+                      fi
+                      if test -z "$haveit"; then
+                        haveit=
+                        for x in $LDFLAGS $LIBPTH; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                                                        LIBPTH="${LIBPTH}${LIBPTH:+ }-L$additional_libdir"
+                          fi
+                        fi
+                        haveit=
+                        for x in $LDFLAGS $LTLIBPTH; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                                                        LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }-L$additional_libdir"
+                          fi
+                        fi
+                      fi
+                    fi
+                    ;;
+                  -R*)
+                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
+                    if test "$enable_rpath" != no; then
+                                                                  haveit=
+                      for x in $rpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        rpathdirs="$rpathdirs $dir"
+                      fi
+                                                                  haveit=
+                      for x in $ltrpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        ltrpathdirs="$ltrpathdirs $dir"
+                      fi
+                    fi
+                    ;;
+                  -l*)
+                                        names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+                    ;;
+                  *.la)
+                                                                                names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+                    ;;
+                  *)
+                                        LIBPTH="${LIBPTH}${LIBPTH:+ }$dep"
+                    LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }$dep"
+                    ;;
+                esac
+              done
+            fi
+          else
+                                                            LIBPTH="${LIBPTH}${LIBPTH:+ }-l$name"
+            LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }-l$name"
+          fi
+        fi
+      fi
+    done
+  done
+  if test "X$rpathdirs" != "X"; then
+    if test -n "$acl_hardcode_libdir_separator"; then
+                        alldirs=
+      for found_dir in $rpathdirs; do
+        alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+      done
+            acl_save_libdir="$libdir"
+      libdir="$alldirs"
+      eval flag=\"$acl_hardcode_libdir_flag_spec\"
+      libdir="$acl_save_libdir"
+      LIBPTH="${LIBPTH}${LIBPTH:+ }$flag"
+    else
+            for found_dir in $rpathdirs; do
+        acl_save_libdir="$libdir"
+        libdir="$found_dir"
+        eval flag=\"$acl_hardcode_libdir_flag_spec\"
+        libdir="$acl_save_libdir"
+        LIBPTH="${LIBPTH}${LIBPTH:+ }$flag"
+      done
+    fi
+  fi
+  if test "X$ltrpathdirs" != "X"; then
+            for found_dir in $ltrpathdirs; do
+      LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }-R$found_dir"
+    done
+  fi
+
+
+
+
+
+
+    ac_cv_libpth_libs="$LIBPTH"
+    ac_cv_libpth_ltlibs="$LTLIBPTH"
+    ac_cv_libpth_cppflags="$INCPTH"
+    ac_cv_libpth_prefix="$LIBPTH_PREFIX"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libpth_libs" >&5
+$as_echo "$ac_cv_libpth_libs" >&6; }
+  LIBPTH="$ac_cv_libpth_libs"
+  LTLIBPTH="$ac_cv_libpth_ltlibs"
+  INCPTH="$ac_cv_libpth_cppflags"
+  LIBPTH_PREFIX="$ac_cv_libpth_prefix"
+
+  for element in $INCPTH; do
+    haveit=
+    for x in $CPPFLAGS; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+      if test "X$x" = "X$element"; then
+        haveit=yes
+        break
+      fi
+    done
+    if test -z "$haveit"; then
+      CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
+    fi
+  done
+
+
+
+
+      HAVE_LIBPTH=yes
+
+
+
+      gl_have_pth=
+      gl_save_LIBS="$LIBS"
+      LIBS="$LIBS $LIBPTH"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pth.h>
+int
+main ()
+{
+pth_self();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gl_have_pth=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+      LIBS="$gl_save_LIBS"
+      if test -n "$gl_have_pth"; then
+        gl_threads_api=pth
+        LIBTHREAD="$LIBPTH"
+        LTLIBTHREAD="$LTLIBPTH"
+        LIBMULTITHREAD="$LIBTHREAD"
+        LTLIBMULTITHREAD="$LTLIBTHREAD"
+
+$as_echo "#define USE_PTH_THREADS 1" >>confdefs.h
+
+        if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
+          if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+
+$as_echo "#define USE_PTH_THREADS_WEAK 1" >>confdefs.h
+
+            LIBTHREAD=
+            LTLIBTHREAD=
+          fi
+        fi
+      else
+        CPPFLAGS="$gl_save_CPPFLAGS"
+      fi
+    fi
+    if test -z "$gl_have_pthread"; then
+      case "$gl_use_threads" in
+        yes | windows | win32) # The 'win32' is for backward compatibility.
+          if { case "$host_os" in
+                 mingw*) true;;
+                 *) false;;
+               esac
+             }; then
+            gl_threads_api=windows
+
+$as_echo "#define USE_WINDOWS_THREADS 1" >>confdefs.h
+
+          fi
+          ;;
+      esac
+    fi
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for multithread API to use" >&5
+$as_echo_n "checking for multithread API to use... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_threads_api" >&5
+$as_echo "$gl_threads_api" >&6; }
+
+
+
+
+
+
+
+
+
+
+  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_MBTOWC=0;
+  GNULIB_MKDTEMP=0;
+  GNULIB_MKOSTEMP=0;
+  GNULIB_MKOSTEMPS=0;
+  GNULIB_MKSTEMP=0;
+  GNULIB_MKSTEMPS=0;
+  GNULIB_POSIX_OPENPT=0;
+  GNULIB_PTSNAME=0;
+  GNULIB_PTSNAME_R=0;
+  GNULIB_PUTENV=0;
+  GNULIB_RANDOM=0;
+  GNULIB_RANDOM_R=0;
+  GNULIB_REALLOC_POSIX=0;
+  GNULIB_REALPATH=0;
+  GNULIB_RPMATCH=0;
+  GNULIB_SECURE_GETENV=0;
+  GNULIB_SETENV=0;
+  GNULIB_STRTOD=0;
+  GNULIB_STRTOLL=0;
+  GNULIB_STRTOULL=0;
+  GNULIB_SYSTEM_POSIX=0;
+  GNULIB_UNLOCKPT=0;
+  GNULIB_UNSETENV=0;
+  GNULIB_WCTOMB=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_POSIX_OPENPT=1;
+  HAVE_PTSNAME=1;
+  HAVE_PTSNAME_R=1;
+  HAVE_RANDOM=1;
+  HAVE_RANDOM_H=1;
+  HAVE_RANDOM_R=1;
+  HAVE_REALPATH=1;
+  HAVE_RPMATCH=1;
+  HAVE_SECURE_GETENV=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_MBTOWC=0;
+  REPLACE_MKSTEMP=0;
+  REPLACE_PTSNAME=0;
+  REPLACE_PTSNAME_R=0;
+  REPLACE_PUTENV=0;
+  REPLACE_RANDOM_R=0;
+  REPLACE_REALLOC=0;
+  REPLACE_REALPATH=0;
+  REPLACE_SETENV=0;
+  REPLACE_STRTOD=0;
+  REPLACE_UNSETENV=0;
+  REPLACE_WCTOMB=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 ${gl_cv_func_malloc_posix+:} false; then :
   $as_echo_n "(cached) " >&6
 else
 
@@ -19932,6 +21351,17 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 
 
+ac_fn_c_check_decl "$LINENO" "alarm" "ac_cv_have_decl_alarm" "$ac_includes_default"
+if test "x$ac_cv_have_decl_alarm" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ALARM $ac_have_decl
+_ACEOF
+
 { $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 ${ac_cv_c_restrict+:} false; then :
@@ -19980,6 +21410,78 @@ _ACEOF
 
 
 
+      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" = xyes; 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 ${ac_cv_func_malloc_0_nonnull+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  case "$host_os" in
+          # Guess yes on platforms where we know the result.
+          *-gnu* | freebsd* | netbsd* | openbsd* \
+          | hpux* | solaris* | cygwin* | mingw*)
+            ac_cv_func_malloc_0_nonnull=yes ;;
+          # If we don't know, assume the worst.
+          *) ac_cv_func_malloc_0_nonnull=no ;;
+        esac
+
+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 :
+  gl_cv_func_malloc_0_nonnull=1
+else
+  gl_cv_func_malloc_0_nonnull=0
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define MALLOC_0_IS_NONNULL $gl_cv_func_malloc_0_nonnull
+_ACEOF
+
+
+
+
 
 
 
@@ -20918,12 +22420,32 @@ fi
 
 
 
-  GNULIB_FFS=0;
-    HAVE_FFS=1;
-  HAVE_STRCASECMP=1;
-  HAVE_DECL_STRNCASECMP=1;
+
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
+if test "x$ac_cv_type_mode_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define mode_t int
+_ACEOF
+
+fi
+
 
 
+    WINDOWS_64_BIT_OFF_T=0
 
 
 
@@ -20938,20 +22460,17 @@ fi
 
 
      if test $gl_cv_have_include_next = yes; then
-       gl_cv_next_strings_h='<'strings.h'>'
+       gl_cv_next_sys_types_h='<'sys/types.h'>'
      else
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <strings.h>" >&5
-$as_echo_n "checking absolute name of <strings.h>... " >&6; }
-if ${gl_cv_next_strings_h+:} false; then :
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <sys/types.h>" >&5
+$as_echo_n "checking absolute name of <sys/types.h>... " >&6; }
+if ${gl_cv_next_sys_types_h+:} false; then :
   $as_echo_n "(cached) " >&6
 else
 
-             if test $ac_cv_header_strings_h = yes; then
-
-
                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <strings.h>
+#include <sys/types.h>
 
 _ACEOF
                                                                                                                         case "$host_os" in
@@ -20969,7 +22488,7 @@ _ACEOF
                esac
                                              gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g'
 
-               gl_header_literal_regex=`echo 'strings.h' \
+               gl_header_literal_regex=`echo 'sys/types.h' \
                                         | sed -e "$gl_make_literal_regex_sed"`
                gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{
                    s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/
@@ -20977,110 +22496,32 @@ _ACEOF
                    p
                    q
                  }'
-                                                            gl_cv_next_strings_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
+                                                            gl_cv_next_sys_types_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
                       sed -n "$gl_absolute_header_sed"`'"'
-          else
-               gl_cv_next_strings_h='<'strings.h'>'
-             fi
 
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_strings_h" >&5
-$as_echo "$gl_cv_next_strings_h" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_sys_types_h" >&5
+$as_echo "$gl_cv_next_sys_types_h" >&6; }
      fi
-     NEXT_STRINGS_H=$gl_cv_next_strings_h
+     NEXT_SYS_TYPES_H=$gl_cv_next_sys_types_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='<'strings.h'>'
+       gl_next_as_first_directive='<'sys/types.h'>'
      else
        # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
-       gl_next_as_first_directive=$gl_cv_next_strings_h
+       gl_next_as_first_directive=$gl_cv_next_sys_types_h
      fi
-     NEXT_AS_FIRST_DIRECTIVE_STRINGS_H=$gl_next_as_first_directive
-
-
-
-
-  if test $ac_cv_header_strings_h = yes; then
-    HAVE_STRINGS_H=1
-  else
-    HAVE_STRINGS_H=0
-  fi
-
-
-
-    for gl_func in ffs strcasecmp strncasecmp; 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 eval \${$as_gl_Symbol+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-    /* Minix 3.1.8 has a bug: <sys/types.h> must be included before
-       <strings.h>.  */
-    #include <sys/types.h>
-    #include <strings.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; }
-    if eval test \"x\$"$as_gl_Symbol"\" = 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
-
-
-
-
-ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = xyes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define pid_t int
-_ACEOF
+     NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H=$gl_next_as_first_directive
 
-fi
 
-ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
-if test "x$ac_cv_type_mode_t" = xyes; then :
 
-else
 
-cat >>confdefs.h <<_ACEOF
-#define mode_t int
-_ACEOF
 
-fi
 
 
 
-    WINDOWS_64_BIT_OFF_T=0
 
 
 
@@ -21183,6 +22624,7 @@ fi
   REPLACE_FTRUNCATE=0;
   REPLACE_GETCWD=0;
   REPLACE_GETDOMAINNAME=0;
+  REPLACE_GETDTABLESIZE=0;
   REPLACE_GETLOGIN_R=0;
   REPLACE_GETGROUPS=0;
   REPLACE_GETPAGESIZE=0;
@@ -21478,7 +22920,7 @@ $as_echo "$gl_cv_func_btowc_eof" >&6; }
     esac
   fi
 
-if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then
+  if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then
 
 
 
@@ -21492,7 +22934,7 @@ if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then
 
   :
 
-fi
+  fi
 
 
 
@@ -21570,6 +23012,10 @@ fi
     localedir='${datarootdir}/locale'
 
   fi
+    if test "x$runstatedir" = x; then
+    runstatedir='${localstatedir}/run'
+
+  fi
 
       pkglibexecdir='${libexecdir}/${PACKAGE}'
 
@@ -21590,6 +23036,7 @@ fi
 
 
 
+
      if test $gl_cv_have_include_next = yes; then
        gl_cv_next_langinfo_h='<'langinfo.h'>'
      else
@@ -21845,7 +23292,7 @@ fi
 
 
 
-LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\""
+  LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\""
 
 
 
@@ -22086,7 +23533,7 @@ fi
     REPLACE_LOCALECONV=1
   fi
 
-if test $REPLACE_LOCALECONV = 1; then
+  if test $REPLACE_LOCALECONV = 1; then
 
 
 
@@ -22110,7 +23557,7 @@ _ACEOF
 fi
 
 
-fi
+  fi
 
 
 
@@ -22122,8 +23569,60 @@ fi
 
 
 
-$as_echo "#define GNULIB_TEST_LOCALECONV 1" >>confdefs.h
+$as_echo "#define GNULIB_TEST_LOCALECONV 1" >>confdefs.h
+
+
+
+
+
+  if test "$gl_threads_api" = posix; then
+    # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the
+    # pthread_rwlock_* functions.
+    ac_fn_c_check_type "$LINENO" "pthread_rwlock_t" "ac_cv_type_pthread_rwlock_t" "#include <pthread.h>
+"
+if test "x$ac_cv_type_pthread_rwlock_t" = xyes; then :
+
+$as_echo "#define HAVE_PTHREAD_RWLOCK 1" >>confdefs.h
+
+fi
+
+    # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+      #include <pthread.h>
+int
+main ()
+{
+
+#if __FreeBSD__ == 4
+error "No, in FreeBSD 4.0 recursive mutexes actually don't work."
+#elif (defined __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ \
+       && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)
+error "No, in Mac OS X < 10.7 recursive mutexes actually don't work."
+#else
+int x = (int)PTHREAD_MUTEX_RECURSIVE;
+return !x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_PTHREAD_MUTEX_RECURSIVE 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  fi
+  :
+
+
 
+cat >>confdefs.h <<_ACEOF
+#define GNULIB_LOCK 1
+_ACEOF
 
 
 
@@ -22199,7 +23698,7 @@ else
 fi
 
 
-if test $REPLACE_MALLOC = 1; then
+  if test $REPLACE_MALLOC = 1; then
 
 
 
@@ -22210,7 +23709,7 @@ if test $REPLACE_MALLOC = 1; then
 
   gl_LIBOBJS="$gl_LIBOBJS malloc.$ac_objext"
 
-fi
+  fi
 
 
 cat >>confdefs.h <<_ACEOF
@@ -22229,7 +23728,7 @@ $as_echo "#define HAVE_MALLOC_POSIX 1" >>confdefs.h
     REPLACE_MALLOC=1
   fi
 
-if test $REPLACE_MALLOC = 1; then
+  if test $REPLACE_MALLOC = 1; then
 
 
 
@@ -22240,7 +23739,7 @@ if test $REPLACE_MALLOC = 1; then
 
   gl_LIBOBJS="$gl_LIBOBJS malloc.$ac_objext"
 
-fi
+  fi
 
 
 
@@ -22819,7 +24318,7 @@ $as_echo "#define MBRTOWC_NUL_RETVAL_BUG 1" >>confdefs.h
     fi
   fi
 
-if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
+  if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
 
 
 
@@ -22833,7 +24332,7 @@ if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
 
   :
 
-fi
+  fi
 
 
 
@@ -23042,7 +24541,7 @@ _ACEOF
     fi
   fi
 
-if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then
+  if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then
 
 
 
@@ -23056,7 +24555,7 @@ if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then
 
   :
 
-fi
+  fi
 
 
 
@@ -23079,7 +24578,7 @@ $as_echo "#define GNULIB_TEST_MBSINIT 1" >>confdefs.h
     REPLACE_MBTOWC=1
   fi
 
-if test $REPLACE_MBTOWC = 1; then
+  if test $REPLACE_MBTOWC = 1; then
 
 
 
@@ -23093,7 +24592,7 @@ if test $REPLACE_MBTOWC = 1; then
 
   :
 
-fi
+  fi
 
 
 
@@ -23179,7 +24678,7 @@ $as_echo "#define REPLACE_NL_LANGINFO 1" >>confdefs.h
     HAVE_NL_LANGINFO=0
   fi
 
-if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then
+  if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then
 
 
 
@@ -23190,7 +24689,7 @@ if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then
 
   gl_LIBOBJS="$gl_LIBOBJS nl_langinfo.$ac_objext"
 
-fi
+  fi
 
 
 
@@ -23222,6 +24721,7 @@ fi
     # 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 ${gl_cv_func_re_compile_pattern_working+:} false; then :
@@ -23232,10 +24732,15 @@ else
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-           #include <locale.h>
-           #include <limits.h>
-           #include <regex.h>
+#include <regex.h>
+
+            #include <locale.h>
+            #include <limits.h>
+            #include <string.h>
+            #if HAVE_DECL_ALARM
+            # include <unistd.h>
+            # include <signal.h>
+            #endif
 
 int
 main ()
@@ -23247,26 +24752,65 @@ int result = 0;
             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 HAVE_DECL_ALARM
+            /* Some builds of glibc go into an infinite loop on this test.  */
+            signal (SIGALRM, SIG_DFL);
+            alarm (2);
+#endif
             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;
+                {
+                  /* 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.  */
+                  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;
+                }
+
+                {
+                  /* This test is from glibc bug 15078.
+                     The test case is from Andreas Schwab in
+                     <http://www.sourceware.org/ml/libc-alpha/2013-01/msg00967.html>.
+                     */
+                  static char const pat[] = "[^x]x";
+                  static char const data[] =
+                    /* <U1000><U103B><U103D><U1014><U103A><U102F><U1015><U103A> */
+                    "\xe1\x80\x80"
+                    "\xe1\x80\xbb"
+                    "\xe1\x80\xbd"
+                    "\xe1\x80\x94"
+                    "\xe1\x80\xba"
+                    "\xe1\x80\xaf"
+                    "\xe1\x80\x95"
+                    "\xe1\x80\xba"
+                    "x";
+                  re_set_syntax (0);
+                  memset (&regex, 0, sizeof regex);
+                  s = re_compile_pattern (pat, sizeof pat - 1, &regex);
+                  if (s)
+                    result |= 1;
+                  else
+                    {
+                      i = re_search (&regex, data, sizeof data - 1,
+                                     0, sizeof data - 1, 0);
+                      if (i != 0 && i != 21)
+                        result |= 1;
+                    }
+                }
+
                 if (! setlocale (LC_ALL, "C"))
                   return 1;
               }
@@ -23444,7 +24988,7 @@ $as_echo "#define regfree rpl_regfree" >>confdefs.h
 
   fi
 
-if test $ac_use_included_regex = yes; then
+  if test $ac_use_included_regex = yes; then
 
 
 
@@ -23460,6 +25004,8 @@ if test $ac_use_included_regex = yes; then
 
 
 
+
+
   for ac_header in libintl.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default"
@@ -23486,7 +25032,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-fi
+  fi
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ssize_t" >&5
 $as_echo_n "checking for ssize_t... " >&6; }
@@ -23737,7 +25283,7 @@ $as_echo "$gl_cv_next_stdlib_h" >&6; }
 
 
 
-    for gl_func in _Exit atoll canonicalize_file_name getloadavg getsubopt grantpt     initstate initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps     posix_openpt ptsname ptsname_r random random_r realpath rpmatch     setenv setstate setstate_r srandom srandom_r     strtod strtoll strtoull unlockpt unsetenv; do
+    for gl_func in _Exit atoll canonicalize_file_name getloadavg getsubopt grantpt     initstate initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps     posix_openpt ptsname ptsname_r random random_r realpath rpmatch     secure_getenv setenv setstate setstate_r srandom srandom_r     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; }
@@ -23786,163 +25332,6 @@ fi
 
 
 
-  for ac_func in strcasecmp
-do :
-  ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp"
-if test "x$ac_cv_func_strcasecmp" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_STRCASECMP 1
-_ACEOF
-
-fi
-done
-
-  if test $ac_cv_func_strcasecmp = no; then
-    HAVE_STRCASECMP=0
-  fi
-
-
-
-  for ac_func in strncasecmp
-do :
-  ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp"
-if test "x$ac_cv_func_strncasecmp" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_STRNCASECMP 1
-_ACEOF
-
-fi
-done
-
-  if test $ac_cv_func_strncasecmp = yes; then
-    HAVE_STRNCASECMP=1
-  else
-    HAVE_STRNCASECMP=0
-  fi
-  ac_fn_c_check_decl "$LINENO" "strncasecmp" "ac_cv_have_decl_strncasecmp" "$ac_includes_default"
-if test "x$ac_cv_have_decl_strncasecmp" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_STRNCASECMP $ac_have_decl
-_ACEOF
-
-  if test $ac_cv_have_decl_strncasecmp = no; then
-    HAVE_DECL_STRNCASECMP=0
-  fi
-
-
-if test $HAVE_STRCASECMP = 0; then
-
-
-
-
-
-
-
-
-  gl_LIBOBJS="$gl_LIBOBJS strcasecmp.$ac_objext"
-
-
-  :
-
-fi
-if test $HAVE_STRNCASECMP = 0; then
-
-
-
-
-
-
-
-
-  gl_LIBOBJS="$gl_LIBOBJS strncasecmp.$ac_objext"
-
-
-  :
-
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-     if test $gl_cv_have_include_next = yes; then
-       gl_cv_next_sys_types_h='<'sys/types.h'>'
-     else
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <sys/types.h>" >&5
-$as_echo_n "checking absolute name of <sys/types.h>... " >&6; }
-if ${gl_cv_next_sys_types_h+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-
-               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-
-_ACEOF
-                                                                                                                        case "$host_os" in
-                 aix*) gl_absname_cpp="$ac_cpp -C" ;;
-                 *)    gl_absname_cpp="$ac_cpp" ;;
-               esac
-
-               case "$host_os" in
-                 mingw*)
-                                                                                                                                     gl_dirsep_regex='[/\\]'
-                   ;;
-                 *)
-                   gl_dirsep_regex='\/'
-                   ;;
-               esac
-                                             gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g'
-
-               gl_header_literal_regex=`echo 'sys/types.h' \
-                                        | sed -e "$gl_make_literal_regex_sed"`
-               gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{
-                   s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/
-                   s|^/[^/]|//&|
-                   p
-                   q
-                 }'
-                                                            gl_cv_next_sys_types_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
-                      sed -n "$gl_absolute_header_sed"`'"'
-
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_sys_types_h" >&5
-$as_echo "$gl_cv_next_sys_types_h" >&6; }
-     fi
-     NEXT_SYS_TYPES_H=$gl_cv_next_sys_types_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='<'sys/types.h'>'
-     else
-       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
-       gl_next_as_first_directive=$gl_cv_next_sys_types_h
-     fi
-     NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H=$gl_next_as_first_directive
-
-
-
-
-
-
-
-
-
-
 
 
 
@@ -24499,7 +25888,7 @@ $as_echo "$gl_cv_func_wcrtomb_retval" >&6; }
     fi
   fi
 
-if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then
+  if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then
 
 
 
@@ -24513,7 +25902,7 @@ if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then
 
   :
 
-fi
+  fi
 
 
 
@@ -24542,8 +25931,6 @@ $as_echo "#define GNULIB_TEST_WCRTOMB 1" >>confdefs.h
 
 
 
-
-
   if test $gt_cv_c_wint_t = yes; then
     HAVE_WINT_T=1
   else
@@ -24957,7 +26344,7 @@ then
     # curlprivatereq=
     # curlprivatelibs=
     libdap_pkgconfig_libcurl=yes
-    libdap_libcurl_module='libcurl >= 7.10.6'
+    libdap_libcurl_module='libcurl >= 7.19.0'
 
 
 if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
@@ -25158,12 +26545,12 @@ $as_echo "yes; used pkg-config" >&6; }
     then
 	   version_libcurl=`curl-config --version | sed 's at libcurl \(.*\)@\1@'`
 
-           as_arg_v1="$version_libcurl"
-as_arg_v2="7.10.6"
+       as_arg_v1="$version_libcurl"
+as_arg_v2="7.19.0"
 awk "$as_awk_strverscmp" v1="$as_arg_v1" v2="$as_arg_v2" /dev/null
 case $? in #(
   1) :
-    as_fn_error $? "I could not find libcurl 7.10.6 or newer, found $version_libcurl" "$LINENO" 5 ;; #(
+    as_fn_error $? "I could not find libcurl 7.19.0 or newer, found $version_libcurl" "$LINENO" 5 ;; #(
   0) :
      ;; #(
   2) :
@@ -25218,7 +26605,7 @@ fi
 if test -z "$xml_set"
 then
 libdap_pkgconfig_libxml2=yes
-libdap_libxml2_module='libxml-2.0 >= 2.6.16'
+libdap_libxml2_module='libxml-2.0 >= 2.7.0'
 
 pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML2" >&5
@@ -25303,11 +26690,11 @@ then
 	version_libxml2=`xml2-config --version`
 
         as_arg_v1="$version_libxml2"
-as_arg_v2="2.6.16"
+as_arg_v2="2.7.0"
 awk "$as_awk_strverscmp" v1="$as_arg_v1" v2="$as_arg_v2" /dev/null
 case $? in #(
   1) :
-    as_fn_error $? "I could not find libxml2 2.6.16 or newer" "$LINENO" 5 ;; #(
+    as_fn_error $? "I could not find libxml2 2.7.0 or newer" "$LINENO" 5 ;; #(
   0) :
      ;; #(
   2) :
@@ -25318,8 +26705,8 @@ esac
 
 	XML2_LIBS="`xml2-config --libs`"
 		XML2_CFLAGS="`xml2-config --cflags`"
-	xmlprivatelibs="`xml2-config --libs`"
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; used xml2-config and found version $version_libxml2" >&5
+	xmlprivatelibs="`xml2-config --libs `"
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; used xml2-config and found version $version_libxml2" >&5
 $as_echo "yes; used xml2-config and found version $version_libxml2" >&6; }
 else
 	as_fn_error $? "I could not find ml2-config" "$LINENO" 5
@@ -25575,31 +26962,6 @@ fi
 
 
 
-libdap_libgridfields_module='libgridfields >= 0.7.0'
-
-libgf_ok="no"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
     # Check whether --enable-debug was given.
 if test "${enable_debug+set}" = set; then :
   enableval=$enable_debug; DEBUG=$enableval
@@ -25648,6 +27010,8 @@ fi
 # Check whether --enable-dap4 was given.
 if test "${enable_dap4+set}" = set; then :
   enableval=$enable_dap4;
+else
+  enable_dap4="yes"
 fi
 
 
@@ -25709,12 +27073,91 @@ fi
 
 
 
+coverage=no
+# Check whether --enable-coverage was given.
+if test "${enable_coverage+set}" = set; then :
+  enableval=$enable_coverage;  coverage=yes
+fi
+
+
+if [ "$coverage" = "yes" ]; then
+    if [ "$GCC" = "yes" ]; then
+        CFLAGS="-fprofile-arcs -ftest-coverage $CFLAGS"
+    else
+        as_fn_error $? "Can only enable coverage when using gcc." "$LINENO" 5
+    fi
+fi
+
+# Support for running test cases using valgrind:
+
+use_valgrind=false
+# Check whether --enable-valgrind was given.
+if test "${enable_valgrind+set}" = set; then :
+  enableval=$enable_valgrind;  use_valgrind=true
+fi
+
+
+if [ "$use_valgrind" = "true" ]; then
+    # Extract the first word of "valgrind", so it can be a program name with args.
+set dummy valgrind; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_HAVE_VALGRIND+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$HAVE_VALGRIND"; then
+  ac_cv_prog_HAVE_VALGRIND="$HAVE_VALGRIND" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_HAVE_VALGRIND="yes"
+    $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_prog_HAVE_VALGRIND" && ac_cv_prog_HAVE_VALGRIND="no"
+fi
+fi
+HAVE_VALGRIND=$ac_cv_prog_HAVE_VALGRIND
+if test -n "$HAVE_VALGRIND"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_VALGRIND" >&5
+$as_echo "$HAVE_VALGRIND" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+    if [ "$HAVE_VALGRIND" = "no" ]; then
+        as_fn_error $? "Valgrind not found in PATH. " "$LINENO" 5
+    fi
+fi
+
+ if $use_valgrind; then
+  USE_VALGRIND_TRUE=
+  USE_VALGRIND_FALSE='#'
+else
+  USE_VALGRIND_TRUE='#'
+  USE_VALGRIND_FALSE=
+fi
+
+
+
 
 
 
 
-ac_config_files="$ac_config_files Makefile libdap.pc libdapclient.pc libdapserver.pc main_page.doxygen doxy.conf gl/Makefile tests/Makefile tests/atlocal unit-tests/Makefile unit-tests/cache-testsuite/Makefile"
 
+ac_config_files="$ac_config_files Makefile libdap.pc libdapclient.pc libdapserver.pc main_page.doxygen doxy.conf abi_checker.xml gl/Makefile d4_ce/Makefile tests/Makefile tests/atlocal unit-tests/Makefile unit-tests/cache-testsuite/Makefile"
 
 
 ac_config_files="$ac_config_files dap-config"
@@ -25950,6 +27393,10 @@ if test -z "${BUILD_DEVELOPER_TRUE}" && test -z "${BUILD_DEVELOPER_FALSE}"; then
   as_fn_error $? "conditional \"BUILD_DEVELOPER\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_VALGRIND_TRUE}" && test -z "${USE_VALGRIND_FALSE}"; then
+  as_fn_error $? "conditional \"USE_VALGRIND\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
@@ -26347,7 +27794,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # 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.12.0, which was
+This file was extended by libdap $as_me 3.14.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -26413,7 +27860,7 @@ _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.12.0
+libdap config.status 3.14.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -26930,7 +28377,9 @@ do
     "libdapserver.pc") CONFIG_FILES="$CONFIG_FILES libdapserver.pc" ;;
     "main_page.doxygen") CONFIG_FILES="$CONFIG_FILES main_page.doxygen" ;;
     "doxy.conf") CONFIG_FILES="$CONFIG_FILES doxy.conf" ;;
+    "abi_checker.xml") CONFIG_FILES="$CONFIG_FILES abi_checker.xml" ;;
     "gl/Makefile") CONFIG_FILES="$CONFIG_FILES gl/Makefile" ;;
+    "d4_ce/Makefile") CONFIG_FILES="$CONFIG_FILES d4_ce/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" ;;
diff --git a/configure.ac b/configure.ac
index 5015c8d..61745bd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,10 +2,10 @@
 dnl -*- autoconf -*-
 dnl Process this file with autoconf to produce a configure script.
 
-AC_PREREQ(2.61)
+AC_PREREQ(2.63)
 dnl Update version here and below at LIB_CURRENT, ..., if needed.
-AC_INIT(libdap, 3.12.0, opendap-tech at opendap.org)
-AC_DEFINE(DAP_PROTOCOL_VERSION, ["3.4"], [Highest DAP version implemented?])
+AC_INIT(libdap, 3.14.0, opendap-tech at opendap.org)
+AC_DEFINE(DAP_PROTOCOL_VERSION, ["4.0"], [Highest DAP version implemented?])
 AC_SUBST(DAP_PROTOCOL_VERSION)
 
 AC_CONFIG_SRCDIR([Connect.cc])
@@ -31,8 +31,11 @@ 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 Removed this; only the Array and Sequence classes ever have constraints that 
+dnl need to be evaluated at run time (DAP4) or only Sequences (DAP2). jhrg 9/4/13
+
+dnl AC_DEFINE(EVAL, 1, [Should all the classes run ConstraintEvaluator::eval()?])
+dnl 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'
@@ -41,8 +44,8 @@ dnl to default values otherwise.
 AC_CANONICAL_HOST
 AC_SUBST(host)
 
-DAPLIB_CURRENT=16
-DAPLIB_AGE=5
+DAPLIB_CURRENT=18
+DAPLIB_AGE=1
 DAPLIB_REVISION=0
 AC_SUBST(DAPLIB_CURRENT)
 AC_SUBST(DAPLIB_AGE)
@@ -51,8 +54,8 @@ AC_SUBST(DAPLIB_REVISION)
 LIBDAP_VERSION="$DAPLIB_CURRENT:$DAPLIB_REVISION:$DAPLIB_AGE"
 AC_SUBST(LIBDAP_VERSION)
 
-CLIENTLIB_CURRENT=5
-CLIENTLIB_AGE=2
+CLIENTLIB_CURRENT=7
+CLIENTLIB_AGE=1
 CLIENTLIB_REVISION=0
 AC_SUBST(CLIENTLIB_CURRENT)
 AC_SUBST(CLIENTLIB_AGE)
@@ -61,8 +64,8 @@ AC_SUBST(CLIENTLIB_REVISION)
 CLIENTLIB_VERSION="$CLIENTLIB_CURRENT:$CLIENTLIB_REVISION:$CLIENTLIB_AGE"
 AC_SUBST(CLIENTLIB_VERSION)
 
-SERVERLIB_CURRENT=12
-SERVERLIB_AGE=5
+SERVERLIB_CURRENT=13
+SERVERLIB_AGE=6
 SERVERLIB_REVISION=0
 AC_SUBST(SERVERLIB_CURRENT)
 AC_SUBST(SERVERLIB_AGE)
@@ -87,6 +90,8 @@ else
     AM_CONDITIONAL([COMPILER_IS_GCC],[false])
 fi
 
+dnl AC_PROG_YACC
+dnl AC_PROG_LEX
 AM_PROG_LEX
 AC_PROG_INSTALL
 AC_PROG_LN_S
@@ -98,12 +103,33 @@ 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 We have found bison; get its version
+bison_version=`bison --version | sed -n '/^bison.*/p' | sed 's at .* \(.*\)@\1@'`
+
+AC_MSG_CHECKING([for bison 3.0])
+
+# This was used to set a conditional in the d4_ce/Makefile.am to build
+# the DAP4 parsers using bison 3 or get pre-built sources from a set
+# of template files. That didn't work on some linux machines, so bison
+# 3 is a requirement for building until that gets sorted out. jhrg 4/5/15
+dnl AS_VERSION_COMPARE(["$bison_version"], ["3.0"], 
+dnl 	[AM_CONDITIONAL([BISON3], [false])],
+dnl 	[AM_CONDITIONAL([BISON3], [true])],
+dnl 	[AM_CONDITIONAL([BISON3], [true])])
+        
+AS_VERSION_COMPARE(["$bison_version"], ["3.0"], 
+	[AC_MSG_ERROR([not found])],
+	[ ],
+	[ ])
+
+AC_MSG_RESULT([found vesion $bison_version])
+
 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])
+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 uuid/uuid.h])
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -165,7 +191,7 @@ then
     # curlprivatereq=
     # curlprivatelibs=
     libdap_pkgconfig_libcurl=yes
-    libdap_libcurl_module='libcurl >= 7.10.6'
+    libdap_libcurl_module='libcurl >= 7.19.0'
     PKG_CHECK_MODULES([CURL],[$libdap_libcurl_module],,
         [libdap_pkgconfig_libcurl=no])
     AC_MSG_CHECKING([for libcurl])
@@ -179,8 +205,8 @@ then
     then
 	   version_libcurl=`curl-config --version | sed 's at libcurl \(.*\)@\1@'`
 
-           AS_VERSION_COMPARE(["$version_libcurl"], ["7.10.6"], 
-                [AC_MSG_ERROR([I could not find libcurl 7.10.6 or newer, found $version_libcurl])])
+       AS_VERSION_COMPARE(["$version_libcurl"], ["7.19.0"], 
+                [AC_MSG_ERROR([I could not find libcurl 7.19.0 or newer, found $version_libcurl])])
         
 	   CURL_LIBS="`curl-config --libs`"
 	   CURL_STATIC_LIBS=$CURL_LIBS
@@ -221,7 +247,7 @@ fi
 if test -z "$xml_set"
 then
 libdap_pkgconfig_libxml2=yes
-libdap_libxml2_module='libxml-2.0 >= 2.6.16'
+libdap_libxml2_module='libxml-2.0 >= 2.7.0'
 PKG_CHECK_MODULES([XML2],[$libdap_libxml2_module], ,[libdap_pkgconfig_libxml2=no])
 AC_MSG_CHECKING([for libxml2])
 if test $libdap_pkgconfig_libxml2 = 'yes'
@@ -234,13 +260,14 @@ elif xml2-config --version > /dev/null 2>&1
 then
 	version_libxml2=`xml2-config --version`
 
-        AS_VERSION_COMPARE(["$version_libxml2"], ["2.6.16"], 
-                [AC_MSG_ERROR([I could not find libxml2 2.6.16 or newer])])
+        AS_VERSION_COMPARE(["$version_libxml2"], ["2.7.0"], 
+                [AC_MSG_ERROR([I could not find libxml2 2.7.0 or newer])])
         
 	XML2_LIBS="`xml2-config --libs`"
 	dnl XML2_STATIC_LIBS=$XML2_LIBS
 	XML2_CFLAGS="`xml2-config --cflags`"
-	xmlprivatelibs="`xml2-config --libs`"
+	xmlprivatelibs="`xml2-config --libs `"
+	dnl `
 	AC_MSG_RESULT([yes; used xml2-config and found version $version_libxml2])
 else
 	AC_MSG_ERROR([I could not find ml2-config])
@@ -267,127 +294,6 @@ AM_PATH_CPPUNIT(1.12.0,
 	[AM_CONDITIONAL([CPPUNIT], [true])],
 	[AM_CONDITIONAL([CPPUNIT], [false])])
 
-dnl When pkgconfig support is added, use this
-libdap_libgridfields_module='libgridfields >= 0.7.0'
-
-libgf_ok="no"
-
-dnl AC_ARG_WITH([gridfields],
-dnl     AC_HELP_STRING([--with-gridfields=path], [Use the gridfields library at this location.]),
-dnl     [if test "$withval" = "yes"
-dnl      then
-dnl          AC_MSG_ERROR([You must supply a path when using --with-gridfields; try --enable-gridfields.])
-dnl      else
-dnl          AC_MSG_NOTICE([Using $withval as the GridFields prefix directory.])
-dnl          GF_LIBS="-L$withval/lib -lgridfields"
-dnl          GF_CFLAGS="-I$withval/include"
-dnl          AC_DEFINE([GRIDFIELDS],[1],[define if gridfields lib is present])
-dnl          libgf_ok="yes"
-dnl      fi],
-dnl     [])
-
-dnl AC_ARG_ENABLE([gridfields],
-dnl     AC_HELP_STRING([--enable-gridfields], [Enable libgridfields-based server functions (default is NO)]))
-
-dnl if test "$libgf_ok" = "no" -a "$enable_gridfields" = "yes"
-dnl then
-     
-dnl AC_MSG_CHECKING([for libgridfields])
-dnl if gridfields-config --version > /dev/null 2>&1
-dnl then
-dnl     version_libgf=`gridfields-config --version | sed 's at libgridfields \(.*\)@\1@'`
-
-dnl     version_M=`echo $version_libgf | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\1@'`
-dnl     version_m=`echo $version_libgf | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\2@'`
-dnl     version_m_m=`echo $version_libgf | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\3@'`
-    
-dnl     dnl Test for several different versions of libgridfields
-    
-dnl     if test $version_M -gt 0
-dnl     then
-dnl         libgf_ok='yes'
-dnl     elif test $version_M -eq 0 && test $version_m -gt 7
-dnl     then
-dnl         libgf_ok='yes'
-dnl     elif test $version_M -eq 0 && test $version_m -eq 7 && test $version_m_m -gt 0
-dnl     then
-dnl         libgf_ok='yes'
-dnl     else
-dnl         libgf_ok='no'
-dnl     fi
-
-dnl     if test "$libgf_ok"="no"
-dnl     then
-dnl         AC_MSG_ERROR([must have libgf 0.7.0 or greater, found $version_libgf])
-dnl     fi
-
-dnl     GF_LIBS="`gridfields-config --libs`"
-dnl     GF_CFLAGS="`gridfields-config --cflags`"
-
-dnl     AC_DEFINE([GRDIFIELDS],[1],[define if gridfields lib is present])
-dnl     AC_MSG_RESULT([yes; used gridfields-config])
-dnl else
-dnl     AC_MSG_ERROR([I could not find libgridfields])
-dnl fi
-
-dnl fi
-
-dnl AC_SUBST([GF_LIBS])
-dnl AC_SUBST([GF_CFLAGS])
-
-dnl if test "$libgf_ok" = "yes"
-dnl then
-dnl     echo "Set gridfields CFLAGS to $GF_CFLAGS"
-dnl     echo "Set gridfields LIBS to $GF_LIBS"
-dnl     AM_CONDITIONAL([USING_GRIDFIELDS],[true])
-dnl else
-dnl     AM_CONDITIONAL([USING_GRIDFIELDS],[false])
-dnl fi
-
-dnl # Which, if any, copy of GDAL should be used for the build?
-dnl GDAL_FOUND=
-
-dnl AC_ARG_WITH(gdal, AS_HELP_STRING([--with-gdal], [Use the copy of GDAL at this location]),
-dnl             with_gdal_prefix="$withval", with_gdal_prefix="")
-
-dnl if test -n "$with_gdal_prefix" -a -x $with_gdal_prefix/bin/gdal-config
-dnl then
-dnl     AC_MSG_NOTICE([Using $with_gdal_prefix as the GDAL prefix directory.])
-dnl     GDAL_LIBS="`$with_gdal_prefix/bin/gdal-config --libs` `$with_gdal_prefix/bin/gdal-config --dep-libs`"
-dnl     GDAL_CFLAGS="`$with_gdal_prefix/bin/gdal-config --cflags`"
-dnl     GDAL_FOUND="yes"
-dnl elif test -n "$with_gdal_prefix"
-dnl then
-dnl     AC_MSG_ERROR([You set the gdal-prefix directory to $with_gdal_prefix, but gdal-config is not there.])
-dnl fi
-
-dnl # Because of the run-time errors encountered when there are competing
-dnl # versions of libs, only include GDAL when explictly told to. NB: see
-dnl # the fileout_gdal handler for another place where GDAL can be added to
-dnl # a running Hyrax server. jhrg 11/23/12
-
-dnl # if test -z "$GDAL_FOUND"
-dnl # then
-dnl #    AX_LIB_GDAL([1.9.0])
-dnl #    if test ! -z "$GDAL_CFLAGS" -a ! -z "$GDAL_LDFLAGS"; then
-dnl #        GDAL_FOUND="yes"
-dnl #    fi
-dnl # fi
-
-dnl AC_SUBST([GDAL_LIBS])
-dnl AC_SUBST([GDAL_CFLAGS])
-
-
-dnl if test -n "$GDAL_FOUND"
-dnl then
-dnl     echo "Set GDAL_CFLAGS to $GDAL_CFLAGS"
-dnl     echo "Set GDAL_LIBS to $GF_LIBS"
-dnl     AM_CONDITIONAL([USING_GDAL],[true])
-dnl     AC_DEFINE([GDAL],[1],[define if gdal lib is present])
-dnl else
-dnl     AM_CONDITIONAL([USING_GDAL],[false])
-dnl fi
-
 DODS_DEBUG_OPTION
 
 dnl See util.cc:dods_root()
@@ -399,7 +305,8 @@ AC_DEFINE_UNQUOTED([LIBDAP_ROOT], ["$prefix"], [Set to the prefix directory])
 fi
 
 AC_ARG_ENABLE([dap4], 
-    AC_HELP_STRING([--enable-dap4], [Enable DAP4 types and responses (default is NO)]))
+    AC_HELP_STRING([--enable-dap4], [Enable DAP4 types and responses (default is Yes)]),
+    [], [enable_dap4="yes"])
 
 AS_IF([test "x$enable_dap4" = "xyes"], [
     dnl Do the stuff needed for enabling the feature
@@ -424,53 +331,36 @@ if test "x$build_developer" = "xtrue"; then
    AC_MSG_NOTICE(["Building developer version"])
 else
    AC_MSG_NOTICE(["Not building developer version"])
-   AC_DEFINE([NDEBUG], [1], [Remove this to activate assert() calls.])
+   AC_DEFINE([NDEBUG], [1], [Define this to suppres assert() calls.])
 fi
 AM_CONDITIONAL([BUILD_DEVELOPER], [test "x$build_developer" = "xtrue"])
 
-dnl AC_ARG_ENABLE([checksums], 
-dnl    AC_HELP_STRING([--enable-checksums], [Enable MD5 checksums for DAP2 (default is NO)]))
-dnl
-dnl echo "enable_checksums = $enable_checksums"
-dnl AS_IF([test "x$enable_checksums" = "xyes"], [
-dnl    dnl Do the stuff needed for enabling the feature
-dnl    dnl echo "Defining checksums! "
-dnl    AC_DEFINE([CHECKSUMS], 1, [Should checksums be generated])
-dnl    AM_CONDITIONAL([CHECKSUMS_DEFINED], [true]) ],
-dnl    [ dnl else enable_checksums is false
-dnl    AM_CONDITIONAL([CHECKSUMS_DEFINED], [false])
-dnl])
+DODS_GCOV_VALGRIND
 
 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 */])
+AH_BOTTOM([#endif /* _config_h */])
 
 AC_CONFIG_FILES([Makefile
                  libdap.pc
                  libdapclient.pc
                  libdapserver.pc
                  main_page.doxygen
-	         doxy.conf
+	             doxy.conf
+	             abi_checker.xml
+
                  gl/Makefile
+                 d4_ce/Makefile
+                 
                  tests/Makefile
                  tests/atlocal
+                 
                  unit-tests/Makefile
                  unit-tests/cache-testsuite/Makefile])
 
-dnl swath2grid/Makefile
-dnl swath2grid/bes.conf
-dnl ugridFunctions/Makefile
-
 AC_CONFIG_FILES([dap-config], [chmod +x dap-config]) 
 	
 AC_OUTPUT
diff --git a/crc.h b/crc.h
new file mode 100644
index 0000000..8b32d8b
--- /dev/null
+++ b/crc.h
@@ -0,0 +1,98 @@
+/*
+ * From Tom Distler
+ * See http://tdistler.com/2011/06/22/crc32-a-simple-c-class
+ */
+
+#ifndef CRC_H_
+#define CRC_H_
+
+static const uint32_t kCrc32Table[256] = {
+    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+    0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+    0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+    0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+    0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+    0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+    0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+    0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+    0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+    0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+    0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+    0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+    0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+    0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+    0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+    0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+    0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+    0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+    0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+    0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+    0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+    0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+    0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+    0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+    0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+    0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+    0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+    0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+    0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+    0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+    0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+    0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+    0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+    0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+    0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+    0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+}; // kCrc32Table
+
+class Crc32
+{
+public:
+    typedef uint32_t checksum;
+
+    Crc32() { Reset(); }
+    ~Crc32() throw() {}
+    void Reset() { _crc = (uint32_t)~0; }
+    void AddData(const uint8_t* pData, const uint32_t length)
+    {
+        uint8_t* pCur = (uint8_t*)pData;
+        uint32_t remaining = length;
+        for (; remaining--; ++pCur)
+            _crc = ( _crc >> 8 ) ^ kCrc32Table[(_crc ^ *pCur) & 0xff];
+    }
+
+    checksum GetCrc32() const { return ~_crc; }
+
+private:
+    uint32_t _crc;
+};
+
+#endif /* CRC_H_ */
diff --git a/ResponseTooBigErr.cc b/d4_ce/D4CEScanner.h
similarity index 53%
copy from ResponseTooBigErr.cc
copy to d4_ce/D4CEScanner.h
index 8847427..f58c2b7 100644
--- a/ResponseTooBigErr.cc
+++ b/d4_ce/D4CEScanner.h
@@ -24,29 +24,53 @@
 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
 
-#include "config.h"
+#ifndef D4CESCANNER_H_
+#define D4CESCANNER_H_
 
-static char rcsid[] not_used =
-    {"$Id: ResponseTooBigErr.cc 27197 2013-10-01 21:29:54Z jimg $"
-    };
+// Only include FlexLexer.h if it hasn't been already included
+#if ! defined(yyFlexLexerOnce)
+#undef yyFlexLexer
+#define yyFlexLexer d4_ceFlexLexer
+#include "FlexLexer.h"
+#endif
 
-#include <string>
+# ifndef YY_NULL
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULL nullptr
+#  else
+#   define YY_NULL 0
+#  endif
+# endif
 
-#include "ResponseTooBigErr.h"
+#undef  YY_DECL
+#define YY_DECL int  libdap::D4CEScanner::yylex()
+
+#include "d4_ce_parser.tab.hh"
 
 namespace libdap {
 
-ResponseTooBigErr::ResponseTooBigErr() : Error()
-{
-    _error_code = unknown_error;
-}
+class D4CEScanner : public d4_ceFlexLexer{
+public:
+
+	D4CEScanner(std::istream &in) : d4_ceFlexLexer(&in), yylval(0), loc(0) { };
+
+	int yylex(libdap::D4CEParser::semantic_type *lval, libdap::location *l)
+	{
+		loc = l;
+		yylval = lval;
+		return( yylex() );
+	}
+
+private:
+	/* hide this one from public view */
+	int yylex();
+
+	/* yyval ptr */
+	libdap::D4CEParser::semantic_type *yylval;
+
+	libdap::location *loc;
+};
 
-ResponseTooBigErr::ResponseTooBigErr(const string &msg) : Error()
-{
-    _error_code = unknown_error;
-    _error_message = "";
-    _error_message += "A caching error was encounterd:\n";
-    _error_message += msg + "\n";
-}
+} /* end namespace libdap */
 
-} // namespace libdap
+#endif /* D4CESCANNER_H_ */
diff --git a/d4_ce/D4ConstraintEvaluator.cc b/d4_ce/D4ConstraintEvaluator.cc
new file mode 100644
index 0000000..5bcfc6a
--- /dev/null
+++ b/d4_ce/D4ConstraintEvaluator.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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <string>
+#include <sstream>
+#include <iterator>
+
+//#define DODS_DEBUG
+
+#include "D4CEScanner.h"
+#include "D4ConstraintEvaluator.h"
+#include "d4_ce_parser.tab.hh"
+#include "DMR.h"
+#include "D4Group.h"
+#include "D4Dimensions.h"
+#include "BaseType.h"
+#include "Array.h"
+#include "Constructor.h"
+
+#include "parser.h"		// for get_ull()
+#include "debug.h"
+
+namespace libdap {
+
+bool D4ConstraintEvaluator::parse(const std::string &expr)
+{
+	d_expr = expr;	// set for error messages. See the %initial-action section of .yy
+
+	std::istringstream iss(expr);
+	D4CEScanner scanner(iss);
+	D4CEParser parser(scanner, *this /* driver */);
+
+	if (trace_parsing()) {
+		parser.set_debug_level(1);
+		parser.set_debug_stream(std::cerr);
+	}
+
+	return parser.parse() == 0;
+}
+
+#if 0
+void
+D4ConstraintEvaluator::set_array_slices(const std::string &id, Array *a)
+{
+    // Test that the indexes and dimensions match in number
+    if (d_indexes.size() != a->dimensions())
+        throw Error("The index constraint for '" + id + "' does not match its rank.");
+
+    Array::Dim_iter d = a->dim_begin();
+    for (vector<index>::iterator i = d_indexes.begin(), e = d_indexes.end(); i != e; ++i) {
+        if ((*i).stride > (unsigned long long)a->dimension_stop(d, false))
+            throw Error("For '" + id + "', the index stride value is greater than the number of elements in the Array");
+        if (!(*i).rest && ((*i).stop) > (unsigned long long)a->dimension_stop(d, false))
+            throw Error("For '" + id + "', the index stop value is greater than the number of elements in the Array");
+
+        D4Dimension *dim = a->dimension_D4dim(d);
+
+        // In a DAP4 CE, specifying '[]' as an array dimension slice has two meanings.
+        // It can mean 'all the elements' of the dimension or 'apply the slicing inherited
+        // from the shared dimension'. The latter might be provide 'all the elements'
+        // but regardless, the Array object must record the CE correctly.
+
+        if (dim && (*i).empty) {
+            a->add_constraint(d, dim);
+        }
+        else {
+            a->add_constraint(d, (*i).start, (*i).stride, (*i).rest ? -1 : (*i).stop);
+        }
+
+        ++d;
+    }
+
+    d_indexes.clear();
+}
+#endif
+
+void
+D4ConstraintEvaluator::throw_not_found(const string &id, const string &ident)
+{
+    throw Error(d_expr + ": The variable " + id + " was not found in the dataset (" + ident + ").");
+}
+
+void
+D4ConstraintEvaluator::throw_not_array(const string &id, const string &ident)
+{
+	throw Error(d_expr + ": The variable '" + id + "' is not an Array variable (" + ident + ").");
+}
+
+void
+D4ConstraintEvaluator::search_for_and_mark_arrays(BaseType *btp)
+{
+	DBG(cerr << "Entering D4ConstraintEvaluator::search_for_and_mark_arrays...(" << btp->name() << ")" << endl);
+
+	assert(btp->is_constructor_type());
+
+	Constructor *ctor = static_cast<Constructor*>(btp);
+	for (Constructor::Vars_iter i = ctor->var_begin(), e = ctor->var_end(); i != e; ++i) {
+		switch ((*i)->type()) {
+		case dods_array_c:
+			DBG(cerr << "Found an array: " << (*i)->name() << endl);
+			mark_array_variable(*i);
+			break;
+		case dods_structure_c:
+		case dods_sequence_c:
+			DBG(cerr << "Found a ctor: " << (*i)->name() << endl);
+			search_for_and_mark_arrays(*i);
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+/**
+ * When an identifier is used in a CE, is becomes part of the 'current projection,'
+ * which means it is part of the set of variable to be sent back to the client. This
+ * method sets a flag in the variable (send_p: send predicate) indicating that.
+ *
+ * @note This will check if the variable is an array and set it's slices accordingly
+ * @param btp BaseType pointer to the variable. Must be non-null
+ * @return The BaseType* to the variable; the send_p flag is set as a side effect.
+ */
+BaseType *
+D4ConstraintEvaluator::mark_variable(BaseType *btp)
+{
+    assert(btp);
+
+    DBG(cerr << "In D4ConstraintEvaluator::mark_variable... (" << btp->name() << "; " << btp->type_name() << ")" << endl);
+
+    btp->set_send_p(true);
+
+    if (btp->type() == dods_array_c ) {
+    	mark_array_variable(btp);
+    }
+
+    // Test for Constructors and marks arrays they contain
+	if (btp->is_constructor_type()) {
+		search_for_and_mark_arrays(btp);
+	}
+	else if (btp->type() == dods_array_c && btp->var() && btp->var()->is_constructor_type()) {
+		search_for_and_mark_arrays(btp->var());
+	}
+
+    // Now set the parent variables
+    BaseType *parent = btp->get_parent();
+    while (parent) {
+        parent->BaseType::set_send_p(true); // Just set the parent using BaseType's impl.
+        parent = parent->get_parent();
+    }
+
+    return btp;
+}
+
+/**
+ * Add an array to the current projection with slicing. Calling this method will result
+ * in the array being returned with anonymous dimensions.
+ *
+ * @note If id is an array that has shared dimensions and uses '[]' where a shared dimension
+ * is found and if that shared dimension has been sliced, then the slice is used as the array's
+ * slice for that dimension (there must be an easier way to explain that...)
+ *
+ * @param id
+ * @return The BaseType* to the Array variable; the send_p and slicing information is
+ * set as a side effect.
+ */
+BaseType *
+D4ConstraintEvaluator::mark_array_variable(BaseType *btp)
+{
+	assert(btp->type() == dods_array_c);
+
+	Array *a = static_cast<Array*>(btp);
+
+	// If an array appears in a CE without the slicing operators ([]) we still have to
+	// call set_user_by_projected_var(true) for all of it's sdims for them to appear in
+	// the CDMR.
+	if (d_indexes.empty()) {
+	    for (Array::Dim_iter d = a->dim_begin(), de = a->dim_end(); d != de; ++d) {
+	        D4Dimension *dim = a->dimension_D4dim(d);
+	        if (dim) {
+	        	a->add_constraint(d, dim);
+	        }
+	    }
+	}
+    else {
+        // Test that the indexes and dimensions match in number
+        if (d_indexes.size() != a->dimensions())
+            throw Error("The index constraint for '" + btp->name() + "' does not match its rank.");
+
+        Array::Dim_iter d = a->dim_begin();
+        for (vector<index>::iterator i = d_indexes.begin(), e = d_indexes.end(); i != e; ++i) {
+            if ((*i).stride > (unsigned long long) a->dimension_stop(d, false))
+                throw Error(
+                        "For '" + btp->name()
+                                + "', the index stride value is greater than the number of elements in the Array");
+            if (!(*i).rest && ((*i).stop) > (unsigned long long) a->dimension_stop(d, false))
+                throw Error(
+                        "For '" + btp->name()
+                                + "', the index stop value is greater than the number of elements in the Array");
+
+            D4Dimension *dim = a->dimension_D4dim(d);
+
+            // In a DAP4 CE, specifying '[]' as an array dimension slice has two meanings.
+            // It can mean 'all the elements' of the dimension or 'apply the slicing inherited
+            // from the shared dimension'. The latter might be provide 'all the elements'
+            // but regardless, the Array object must record the CE correctly.
+
+            if (dim && (*i).empty) {
+                a->add_constraint(d, dim);  // calls set_used_by_projected_var(true) + more
+            }
+            else {
+                a->add_constraint(d, (*i).start, (*i).stride, (*i).rest ? -1 : (*i).stop);
+            }
+
+            ++d;
+        }
+
+        d_indexes.clear();
+    }
+
+	return btp;
+}
+
+/**
+ * Add an array to the current projection with slicing. Calling this method will result
+ * in the array being returned with anonymous dimensions.
+ * @param id
+ * @return The BaseType* to the Array variable; the send_p and slicing information is
+ * set as a side effect.
+ */
+D4Dimension *
+D4ConstraintEvaluator::slice_dimension(const std::string &id, const index &i)
+{
+    D4Dimension *dim = dmr()->root()->find_dim(id);
+
+    if (i.stride > dim->size())
+        throw Error("For '" + id + "', the index stride value is greater than the size of the dimension");
+    if (!i.rest && (i.stop > dim->size() - 1))
+        throw Error("For '" + id + "', the index stop value is greater than the size of the dimension");
+
+    dim->set_constraint(i.start, i.stride, i.rest ? dim->size() - 1: i.stop);
+
+    return dim;
+}
+
+D4ConstraintEvaluator::index
+D4ConstraintEvaluator::make_index(const std::string &i)
+{
+	unsigned long long v = get_ull(i.c_str());
+	return index(v, 1, v, false, false /*empty*/);
+}
+
+D4ConstraintEvaluator::index
+D4ConstraintEvaluator::make_index(const std::string &i, const std::string &s, const std::string &e)
+{
+	return index(get_ull(i.c_str()), get_ull(s.c_str()), get_ull(e.c_str()), false, false /*empty*/);
+}
+
+D4ConstraintEvaluator::index
+D4ConstraintEvaluator::make_index(const std::string &i, unsigned long long s, const std::string &e)
+{
+	return index(get_ull(i.c_str()), s, get_ull(e.c_str()), false, false /*empty*/);
+}
+
+D4ConstraintEvaluator::index
+D4ConstraintEvaluator::make_index(const std::string &i, const std::string &s)
+{
+	return index(get_ull(i.c_str()), get_ull(s.c_str()), 0, true, false /*empty*/);
+}
+
+D4ConstraintEvaluator::index
+D4ConstraintEvaluator::make_index(const std::string &i, unsigned long long s)
+{
+	return index(get_ull(i.c_str()), s, 0, true, false /*empty*/);
+}
+
+// This method is called from the parser (see d4_ce_parser.yy, down in the code
+// section). This will be called during the call to D4CEParser::parse(), that
+// is inside D4ConstraintEvaluator::parse(...)
+void
+D4ConstraintEvaluator::error(const libdap::location &l, const std::string &m)
+{
+	std::cerr << l << ": " << m << std::endl;
+}
+
+} /* namespace libdap */
diff --git a/d4_ce/D4ConstraintEvaluator.h b/d4_ce/D4ConstraintEvaluator.h
new file mode 100644
index 0000000..bc58e72
--- /dev/null
+++ b/d4_ce/D4ConstraintEvaluator.h
@@ -0,0 +1,132 @@
+
+// -*- 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef D4CEDRIVER_H_
+#define D4CEDRIVER_H_
+
+#include <string>
+#include <vector>
+#include <stack>
+
+namespace libdap {
+
+class location;
+class DMR;
+class BaseType;
+class Array;
+class D4Dimension;
+
+/**
+ * Driver for the DAP4 Constraint Expression parser.
+ */
+class D4ConstraintEvaluator {
+	struct index {
+		// start and stride are simple numbers; stop is either the stopping index or
+		// if to_end is true, is ignored and the subset runs to the end of the dimension
+		unsigned long long start, stride, stop;
+		// true if the slice indicates it does not contain a specific 'stop' value but
+		// goes to the end, whatever that value is.
+		bool rest;
+		// An empty slice ([]) means either the entire dimension or apply the shared
+		// dimension slice, depending on whether the corresponding shared dimension has
+		// been sliced.
+		bool empty;
+
+		// Added because the parser code needs it. Our code does not use this. jhrg 11/26/13
+		index(): start(0), stride(0), stop(0), rest(false), empty(false) {}
+		index(unsigned long long i, unsigned long long s, unsigned long long e, bool r, bool em)
+			: start(i), stride(s), stop(e), rest(r), empty(em) {}
+	};
+
+	index make_index() { return index(0, 1, 0, true /*rest*/, true /*empty*/); }
+
+	index make_index(const std::string &is);
+
+	index make_index(const std::string &i, const std::string &s, const std::string &e);
+	index make_index(const std::string &i, unsigned long long s, const std::string &e);
+
+	index make_index(const std::string &i, const std::string &s);
+	index make_index(const std::string &i, unsigned long long s);
+
+	bool d_trace_scanning;
+	bool d_trace_parsing;
+	bool d_result;
+	std::string d_expr;
+
+	DMR *d_dmr;
+
+	std::vector<index> d_indexes;
+
+	std::stack<BaseType*> d_basetype_stack;
+
+	// d_expr should be set by parse! Its value is used by the parser right before
+	// the actual parsing operation starts. jhrg 11/26/13
+	std::string *expression() { return &d_expr; }
+#if 0
+	void set_array_slices(const std::string &id, Array *a);
+#endif
+	void search_for_and_mark_arrays(BaseType *btp);
+	BaseType *mark_variable(BaseType *btp);
+	BaseType *mark_array_variable(BaseType *btp);
+
+	D4Dimension *slice_dimension(const std::string &id, const index &i);
+
+	void push_index(const index &i) { d_indexes.push_back(i); }
+
+	void push_basetype(BaseType *btp) { d_basetype_stack.push(btp); }
+	BaseType *top_basetype() const { return d_basetype_stack.empty() ? 0 : d_basetype_stack.top(); }
+	// throw on pop with an empty stack?
+	void pop_basetype() { d_basetype_stack.pop(); }
+
+	void throw_not_found(const std::string &id, const std::string &ident);
+	void throw_not_array(const std::string &id, const std::string &ident);
+
+	friend class D4CEParser;
+
+public:
+	D4ConstraintEvaluator() : d_trace_scanning(false), d_trace_parsing(false), d_result(false), d_expr(""), d_dmr(0) { }
+	D4ConstraintEvaluator(DMR *dmr) : d_trace_scanning(false), d_trace_parsing(false), d_result(false), d_expr(""), d_dmr(dmr) { }
+
+	virtual ~D4ConstraintEvaluator() { }
+
+	bool parse(const std::string &expr);
+
+	bool trace_scanning() const { return d_trace_scanning; }
+	void set_trace_scanning(bool ts) { d_trace_scanning = ts; }
+
+	bool trace_parsing() const { return d_trace_parsing; }
+	void set_trace_parsing(bool tp) { d_trace_parsing = tp; }
+
+	bool result() const { return d_result; }
+	void set_result(bool r) { d_result = r; }
+
+	DMR *dmr() const { return d_dmr; }
+	void set_dmr(DMR *dmr) { d_dmr = dmr; }
+
+	void error(const libdap::location &l, const std::string &m);
+};
+
+} /* namespace libdap */
+#endif /* D4CEDRIVER_H_ */
diff --git a/d4_ce/D4FunctionEvaluator.cc b/d4_ce/D4FunctionEvaluator.cc
new file mode 100644
index 0000000..92204ec
--- /dev/null
+++ b/d4_ce/D4FunctionEvaluator.cc
@@ -0,0 +1,275 @@
+// -*- 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <cstdlib>
+#include <cerrno>
+
+#include <string>
+#include <sstream>
+#include <iterator>
+
+//#define DODS_DEBUG
+
+#include "D4FunctionScanner.h"
+#include "D4FunctionEvaluator.h"
+#include "d4_function_parser.tab.hh"
+
+#include "DMR.h"
+#include "D4Group.h"
+#include "D4RValue.h"
+
+#include "BaseType.h"
+#include "Array.h"
+#include "D4Enum.h"
+
+#include "escaping.h"
+#include "util.h"
+#include "debug.h"
+
+namespace libdap {
+
+/**
+ * Parse the DAP4 function expression.
+ *
+ * Calling this method with a DAP4 function expression builds a
+ * D4RvalueList that can then be evaluated. The list of rvalues
+ * can be accessed or evaluated (using the result() or eval()
+ * methods). Note that the result is a list of rvalues because the
+ * input can be zero or more function expressions.
+ *
+ * @param expr The function expression.
+ * @return True if the parse succeeded, false otherwise.
+ */
+bool D4FunctionEvaluator::parse(const std::string &expr)
+{
+	d_expr = expr;	// set for error messages. See the %initial-action section of .yy
+
+	std::istringstream iss(expr);
+	D4FunctionScanner scanner(iss);
+	D4FunctionParser parser(scanner, *this /* driver */);
+
+	if (trace_parsing()) {
+		parser.set_debug_level(1);
+		parser.set_debug_stream(std::cerr);
+	}
+
+	return parser.parse() == 0;
+}
+
+/**
+ * Evaluate the recently parsed function expression and put the resulting
+ * rvalues (which return values packaged in libdap BaseType objects) into
+ * the top-level Group of the DMR passed as a param here.
+ *
+ * @note The DMR passed to this method can (and usually will) be different
+ * from the DMR passed to the D4FunctionEvaluator constructor. That DMR is
+ * the 'source dataset' for values of variables used by the functions. It
+ * is not generally where the results of evaluating the functions wind up.
+ * Usually, you'll want those results in their own DMR; the functions
+ * effectively make a new dataset. However, you _can_ pass the source dataset
+ * DMR into this method and in that case the new variables will be appended
+ * to its root Group.
+ *
+ * @note This code is really just a place to package results. The actual
+ * evaluation happens in the D4RValue object when values are accessed.
+ * The parse() method here builds the list of D4RValue objects and this
+ * code accesses the values which triggers the function evaluation. Thus,
+ * if you'd like to build a system that performs lazy evaluation, you can
+ * work with the result() method from this class instead of this one.
+ *
+ * @note Calling this method will delete the D4RValueList object built
+ * by the parse() method.
+ *
+ * @param dmr Store the results here
+ * @exception Throws Error if the evaluation fails.
+ */
+void D4FunctionEvaluator::eval(DMR *function_result)
+{
+#if 0
+	ServerFunctionsList *sf_list = ServerFunctionsList::TheList();
+	ServerFunction *scale = new D4TestFunction;
+	sf_list->add_function(scale);
+
+	D4FunctionEvaluator parser(dataset, sf_list);
+	if (ce_parser_debug) parser.set_trace_parsing(true);
+	bool parse_ok = parser.parse(function);
+	if (!parse_ok)
+	Error("Function Expression failed to parse.");
+	else {
+		if (ce_parser_debug) cerr << "Function Parse OK" << endl;
+		D4RValueList *result = parser.result();
+
+		function_result = new DMR(&d4_factory, "function_results");
+#endif
+
+	if (!d_result) throw InternalErr(__FILE__, __LINE__, "Must parse() the function expression before calling eval()");
+
+	D4Group *root = function_result->root();	// Load everything in the root group
+
+	for (D4RValueList::iter i = d_result->begin(), e = d_result->end(); i != e; ++i) {
+		// Copy the BaseTypes; this means all of the function results can
+		// be deleted, which addresses the memory leak issue with function
+		// results. This should also copy the D4Dimensions. jhrg 3/17/14
+		root->add_var((*i)->value(*d_dmr));
+	}
+
+	delete d_result;	// The parser/function allocates the BaseType*s that hold the results.
+	d_result = 0;
+
+	// Variables can use Dimensions and Enumerations, so those need to be copied
+	// from the source dataset to the result. NB: The variables that refer to these
+	// use weak pointers.
+
+	// Make a set of D4Dimensions. For each variable in 'function_result', look
+	// for its dimensions in 'dataset' (by name) and add a pointer to those to the
+	// set. Then copy all the stuff in the set into the root group of 'function_
+	// result.'
+	set<D4Dimension*> dim_set;
+
+	for (Constructor::Vars_iter i = root->var_begin(), ie = root->var_end(); i != ie; ++i) {
+		if ((*i)->is_vector_type()) {
+			Array *a = static_cast<Array*>(*i);
+			for (Array::Dim_iter d = a->dim_begin(), de = a->dim_end(); d != de; ++d) {
+				if (a->dimension_D4dim(d)) {
+					dim_set.insert(a->dimension_D4dim(d));
+				}
+			}
+		}
+	}
+
+	// Copy the D4Dimensions and EnumDefs because this all goes in a new DMR - we don't
+	// want to share those across DMRs because the DMRs delete those (so sharing htem
+	// across DMRs would lead to dangling pointers.
+	for (set<D4Dimension*>::iterator i = dim_set.begin(), e = dim_set.end(); i != e; ++i) {
+		root->dims()->add_dim(*i);
+	}
+
+	// Now lets do the enumerations....
+	set<D4EnumDef*> enum_def_set;
+	for (Constructor::Vars_iter i = root->var_begin(), ie = root->var_end(); i != ie; ++i) {
+		if ((*i)->type() == dods_enum_c) {
+			enum_def_set.insert(static_cast<D4Enum*>(*i)->enumeration());
+		}
+	}
+
+	for (set<D4EnumDef*>::iterator i = enum_def_set.begin(), e = enum_def_set.end(); i != e; ++i) {
+		root->enum_defs()->add_enum(*i);
+	}
+}
+
+// libdap contains functions (in parser-util.cc) that test if a string
+// can be converted to an int32, e.g., but I used a more streamlined
+// approach here. 3/13/14 jhrg
+/**
+ * Build and return a new RValue. Allocates the new D4RValue object.
+ * The code tries first to find the id in the DMR - that is, it checks
+ * first to see if it is a variable in the current dataset. If that
+ * fails it will try to build an unsigned long long, a long long or
+ * a double from the string (in that order). If that fails the code
+ * converts the id into a string.
+ *
+ * @param id An identifier (really a string) parsed from the function
+ * expression. May contain quotes.
+ * @return Return a pointer to the new allocated D4RValue object.
+ */
+D4RValue *
+D4FunctionEvaluator::build_rvalue(const std::string &id)
+{
+    BaseType *btp = 0;
+
+    // Look for the id in the dataset first
+    if (top_basetype()) {
+        btp = top_basetype()->var(id);
+    }
+    else {
+        btp = dmr()->root()->find_var(id);
+    }
+
+    if (btp)
+        return new D4RValue(btp);
+
+    // If the id is not a variable, try to turn it into a constant,
+    // otherwise, its an error.
+    char *end_ptr = 0;
+
+    errno = 0;
+    long long ll_val = strtoll(id.c_str(), &end_ptr, 0);
+    if (*end_ptr == '\0' && errno == 0)
+    	return new D4RValue(ll_val);
+
+    // Test for unsigned after signed since strtoull() accepts a minus sign
+    // (and will return a huge number if that's the case). jhrg 3/13/14
+    errno = 0;
+    unsigned long long ull_val = strtoull(id.c_str(), &end_ptr, 0);
+    if (*end_ptr == '\0' && errno == 0)
+    	return new D4RValue(ull_val);
+
+    errno = 0;
+    double d_val = strtod(id.c_str(), &end_ptr);
+    if (*end_ptr == '\0' && errno == 0)
+    	return new D4RValue(d_val);
+
+    // To be a valid string, the id must be quoted (using double quotes)
+    if (is_quoted(id))
+    	return new D4RValue(www2id(id));
+
+    // if it's none of these, return null
+    return 0;
+}
+
+template <typename T>
+std::vector<T> *
+D4FunctionEvaluator::init_arg_list(T val)
+{
+	std::vector<T> *arg_list = new std::vector<T>();
+	if (get_arg_length_hint() > 0) arg_list->reserve(get_arg_length_hint());
+
+	arg_list->push_back(val);
+
+	return arg_list;
+}
+
+// Force an instantiation so this can be called from within the d4_function.yy
+// parser.
+template std::vector<dods_byte> *D4FunctionEvaluator::init_arg_list(dods_byte val);
+template std::vector<dods_int8> *D4FunctionEvaluator::init_arg_list(dods_int8 val);
+template std::vector<dods_uint16> *D4FunctionEvaluator::init_arg_list(dods_uint16 val);
+template std::vector<dods_int16> *D4FunctionEvaluator::init_arg_list(dods_int16 val);
+template std::vector<dods_uint32> *D4FunctionEvaluator::init_arg_list(dods_uint32 val);
+template std::vector<dods_int32> *D4FunctionEvaluator::init_arg_list(dods_int32 val);
+template std::vector<dods_uint64> *D4FunctionEvaluator::init_arg_list(dods_uint64 val);
+template std::vector<dods_int64> *D4FunctionEvaluator::init_arg_list(dods_int64 val);
+template std::vector<dods_float32> *D4FunctionEvaluator::init_arg_list(dods_float32 val);
+template std::vector<dods_float64> *D4FunctionEvaluator::init_arg_list(dods_float64 val);
+
+// This method is called from the parser (see d4_function_parser.yy, down in the code
+// section). This will be called during the call to D4FunctionParser::parse(), that
+// is inside D4FunctionEvaluator::parse(...)
+void
+D4FunctionEvaluator::error(const libdap::location &l, const std::string &m)
+{
+	std::cerr << l << ": " << m << std::endl;
+}
+
+} /* namespace libdap */
diff --git a/d4_ce/D4FunctionEvaluator.h b/d4_ce/D4FunctionEvaluator.h
new file mode 100644
index 0000000..ec65f81
--- /dev/null
+++ b/d4_ce/D4FunctionEvaluator.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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef D4_FUNCTION_DRIVER_H_
+#define D4_FUNCTION_DRIVER_H_
+
+#include <string>
+#include <vector>
+#include <stack>
+
+namespace libdap {
+
+class location;
+
+class BaseType;
+class Array;
+class ServerFunctionsList;
+
+class DMR;
+class D4Dimension;
+class D4RValue;
+class D4RValueList;
+
+/**
+ * Driver for the DAP4 Functional expression parser.
+ */
+class D4FunctionEvaluator {
+	bool d_trace_scanning;
+	bool d_trace_parsing;
+	std::string d_expr;
+
+	DMR *d_dmr;
+	ServerFunctionsList *d_sf_list;
+
+	D4RValueList *d_result;
+
+	std::stack<BaseType*> d_basetype_stack;
+
+	unsigned long long d_arg_length_hint;
+
+	// d_expr should be set by parse! Its value is used by the parser right before
+	// the actual parsing operation starts. jhrg 11/26/13
+	std::string *expression() { return &d_expr; }
+
+	void push_basetype(BaseType *btp) { d_basetype_stack.push(btp); }
+	BaseType *top_basetype() const { return d_basetype_stack.empty() ? 0 : d_basetype_stack.top(); }
+	void pop_basetype() { d_basetype_stack.pop(); }
+
+	D4RValue *build_rvalue(const std::string &id);
+
+	friend class D4FunctionParser;
+
+public:
+	D4FunctionEvaluator() : d_trace_scanning(false), d_trace_parsing(false), d_expr(""), d_dmr(0), d_sf_list(0),
+			d_result(0), d_arg_length_hint(0) { }
+	D4FunctionEvaluator(DMR *dmr, ServerFunctionsList *sf_list) : d_trace_scanning(false), d_trace_parsing(false),
+			d_expr(""), d_dmr(dmr), d_sf_list(sf_list), d_result(0), d_arg_length_hint(0) { }
+
+	virtual ~D4FunctionEvaluator() { }
+
+	bool parse(const std::string &expr);
+
+	bool trace_scanning() const { return d_trace_scanning; }
+	void set_trace_scanning(bool ts) { d_trace_scanning = ts; }
+
+	bool trace_parsing() const { return d_trace_parsing; }
+	void set_trace_parsing(bool tp) { d_trace_parsing = tp; }
+
+	/** Get the result of parsing the function(s)
+	 *
+	 * @return The result(s) packages in a D4RValueList
+	 */
+	D4RValueList *result() const { return d_result; }
+	void set_result(D4RValueList *rv_list) { d_result = rv_list; }
+
+	void eval(DMR *dmr);
+
+	unsigned long long get_arg_length_hint() const { return d_arg_length_hint; }
+	void set_arg_length_hint(unsigned long long alh) { d_arg_length_hint = alh; }
+
+	DMR *dmr() const { return d_dmr; }
+	void set_dmr(DMR *dmr) { d_dmr = dmr; }
+
+	ServerFunctionsList *sf_list() const { return d_sf_list; }
+	void set_sf_list(ServerFunctionsList *sf_list) { d_sf_list = sf_list; }
+
+	template <typename t> std::vector<t> *init_arg_list(t val);
+
+	void error(const libdap::location &l, const std::string &m);
+};
+
+} /* namespace libdap */
+#endif /* D4_FUNCTION_DRIVER_H_ */
diff --git a/ResponseTooBigErr.cc b/d4_ce/D4FunctionScanner.h
similarity index 51%
copy from ResponseTooBigErr.cc
copy to d4_ce/D4FunctionScanner.h
index 8847427..2f19724 100644
--- a/ResponseTooBigErr.cc
+++ b/d4_ce/D4FunctionScanner.h
@@ -24,29 +24,53 @@
 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
 
-#include "config.h"
+#ifndef D4_FUNCTION_SCANNER_H_
+#define D4_FUNCTION_SCANNER_H_
 
-static char rcsid[] not_used =
-    {"$Id: ResponseTooBigErr.cc 27197 2013-10-01 21:29:54Z jimg $"
-    };
+// Only include FlexLexer.h if it hasn't been already included
+#if ! defined(yyFlexLexerOnce)
+#undef yyFlexLexer
+#define yyFlexLexer d4_functionFlexLexer
+#include "FlexLexer.h"
+#endif
 
-#include <string>
+# ifndef YY_NULL
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULL nullptr
+#  else
+#   define YY_NULL 0
+#  endif
+# endif
 
-#include "ResponseTooBigErr.h"
+#undef  YY_DECL
+#define YY_DECL int  libdap::D4FunctionScanner::yylex()
+
+#include "d4_function_parser.tab.hh"
 
 namespace libdap {
 
-ResponseTooBigErr::ResponseTooBigErr() : Error()
-{
-    _error_code = unknown_error;
-}
+class D4FunctionScanner : public d4_functionFlexLexer{
+public:
+
+	D4FunctionScanner(std::istream &in) : d4_functionFlexLexer(&in), yylval(0), loc(0) { };
+
+	int yylex(libdap::D4FunctionParser::semantic_type *lval, libdap::location *l)
+	{
+		loc = l;
+		yylval = lval;
+		return( yylex() );
+	}
+
+private:
+	/* hide this one from public view */
+	int yylex();
+
+	/* yyval ptr */
+	libdap::D4FunctionParser::semantic_type *yylval;
+
+	libdap::location *loc;
+};
 
-ResponseTooBigErr::ResponseTooBigErr(const string &msg) : Error()
-{
-    _error_code = unknown_error;
-    _error_message = "";
-    _error_message += "A caching error was encounterd:\n";
-    _error_message += msg + "\n";
-}
+} /* end namespace libdap */
 
-} // namespace libdap
+#endif /* D4_FUNCTION_SCANNER_H_ */
diff --git a/d4_ce/Makefile.am b/d4_ce/Makefile.am
new file mode 100644
index 0000000..a9ec12c
--- /dev/null
+++ b/d4_ce/Makefile.am
@@ -0,0 +1,119 @@
+# Tests
+
+AUTOMAKE_OPTIONS = foreign
+
+# Arrange to build with the backward compatibility mode enabled.
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/d4_ce -I$(srcdir) $(XML2_CFLAGS)
+AM_CXXFLAGS =  
+
+if COMPILER_IS_GCC
+AM_CXXFLAGS += -Wall -W -Wcast-align
+endif
+
+# autoconf/automake includes support for yacc and lex so that the input
+# files for those compilers can be listed in a _SOURCES variable and the
+# build will just work. I had a fair amount of hassle getting that going
+# and then realized that cmake might undo all that effort. Also, the
+# changes are not local to this dir only since I'd have to edit the DAP2
+# grammars as well. I've left the edits in a comments although I'm not sure
+# it ever worked correctly. jhrg 10/21/14
+#
+# AM_YFLAGS= -d
+# AM_LFLAGS = -d
+
+CXXFLAGS_DEBUG = -g3 -O0 -Wall -W -Wcast-align
+TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
+
+if BUILD_DEVELOPER
+AM_CXXFLAGS += $(CXXFLAGS_DEBUG)
+endif
+
+noinst_LTLIBRARIES = libd4_ce_parser.la
+pkginclude_HEADERS = D4ConstraintEvaluator.h D4FunctionEvaluator.h
+
+BUILT_SOURCES = lex.d4_ce.cc lex.d4_function.cc
+# BUILT_SOURCES = d4_ce_parser.hh stack.hh location.hh position.hh d4_function_parser.hh
+
+libd4_ce_parser_la_SOURCES = D4ConstraintEvaluator.cc \
+	D4ConstraintEvaluator.h D4CEScanner.h D4FunctionEvaluator.cc	\
+	D4FunctionEvaluator.h D4FunctionScanner.h d4_ce_parser.tab.cc	\
+	d4_ce_parser.tab.hh lex.d4_ce.cc d4_function_parser.tab.cc	\
+	d4_function_parser.tab.hh lex.d4_function.cc location.hh	\
+	position.hh stack.hh
+
+# d4_ce_parser.yy d4_function_parser.yy d4_ce_scanner.ll d4_function_scanner.ll
+
+# Kludge: If we are not building the scanner/parser from the 
+# grammar sources, make sure to use the scanner class that
+# matches the generated code. This addresses an issue where
+# different versions of flex use 'int' or 'size_t' for some 
+# arguments in the scanner's protected methods. This is not
+# automatically updated to match changes in the gnerated files.
+# jhrg 3/31/15
+#
+# Goog intent behind this idea, but in practice it was not working to
+# build the DAP4 parsers this way. Given more time, it might be
+# something that will work, but for the next release (early April
+# 2015) bison 3.x is going to be a requirement. jhrg 4/5/15
+
+# if !BISON3
+# libd4_ce_parser_la_SOURCES += FlexLexer.h
+# endif 
+
+libd4_ce_parser_la_CXXFLAGS=$(AM_CPPFLAGS)
+
+# Used by both the "have bison 3+'" and "don't have ..." cases
+GEN_GRAM_SRCS=gen_grammar_sources
+
+EXTRA_DIST = d4_ce_parser.yy d4_ce_scanner.ll d4_function_parser.yy d4_function_scanner.ll
+EXTRA_DIST += $(GEN_GRAM_SRCS)
+
+DISTCLEANFILES = 
+
+clean-local:
+	-rm location.hh position.hh stack.hh d4_ce_parser.tab.cc	\
+d4_ce_parser.tab.hh lex.d4_ce.cc d4_function_parser.tab.cc		\
+d4_function_parser.tab.hh lex.d4_function.cc FlexLexer.h
+
+# if BISON3
+# If we have bison3+, use it. Otherwise, use files from git.
+
+lex.d4_ce.cc: d4_ce_scanner.ll d4_ce_parser.tab.cc d4_ce_parser.tab.hh
+	$(LEX) $(LFLAGS) $<
+
+d4_ce_parser.tab.hh d4_ce_parser.tab.cc stack.hh location.hh position.hh: d4_ce_parser.yy
+	$(YACC) $(YFLAGS) $<
+
+lex.d4_function.cc: d4_function_scanner.ll d4_function_parser.tab.cc d4_function_parser.tab.hh
+	$(LEX) $(LFLAGS) $<
+
+d4_function_parser.tab.hh d4_function_parser.tab.cc: d4_function_parser.yy
+	$(YACC) $(YFLAGS) $<
+
+# These rules keep the 'tmp' files up-to-date w/o us having to remember
+# to rule a special target when the grammars change. Including the '.hh'
+# in the rule below is a work-around for the 'FlexLexer.h' which is _not_
+# generated and breaks this scheme otherwise. We could list each file
+# by name, each one prefixed with $(GEN_GRA...). jhrg 3/31/15
+# all-local: $(GEN_GRAM_SRCS)/*.cc.tmp $(GEN_GRAM_SRCS)/*.hh.tmp
+
+# $(GEN_GRAM_SRCS)/%.cc.tmp : %.cc
+# 	cp $< $@
+
+# $(GEN_GRAM_SRCS)/%.hh.tmp: %.hh
+# 	cp $< $@
+
+# $(GEN_GRAM_SRCS)/%.h.tmp: %.h
+# 	cp $< $@
+
+# else
+
+# # The brute force way to get the C++ grammar sources for hosts
+# # w/o bison 3
+
+# % :: $(GEN_GRAM_SRCS)/%.tmp
+# 	cp $< $@
+
+# FlexLexer.h: $(GEN_GRAM_SRCS)/FlexLexer.h.tmp
+# 	cp $< $@
+# endif
diff --git a/tests/Makefile.in b/d4_ce/Makefile.in
similarity index 66%
copy from tests/Makefile.in
copy to d4_ce/Makefile.in
index 5c027c8..2074af8 100644
--- a/tests/Makefile.in
+++ b/d4_ce/Makefile.in
@@ -54,30 +54,32 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 @COMPILER_IS_GCC_TRUE at am__append_1 = -Wall -W -Wcast-align
-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 \
-	$(testheaders_HEADERS) $(top_srcdir)/conf/depcomp
+ at BUILD_DEVELOPER_TRUE@am__append_2 = $(CXXFLAGS_DEBUG)
+subdir = d4_ce
+DIST_COMMON = $(pkginclude_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(top_srcdir)/conf/depcomp
 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/byteswap.m4 $(top_srcdir)/gl/m4/codeset.m4 \
 	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/eealloc.m4 \
 	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/extern-inline.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/lib-ld.m4 $(top_srcdir)/gl/m4/lib-link.m4 \
+	$(top_srcdir)/gl/m4/lib-prefix.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/locale_h.m4 \
-	$(top_srcdir)/gl/m4/localeconv.m4 \
+	$(top_srcdir)/gl/m4/localeconv.m4 $(top_srcdir)/gl/m4/lock.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/mbtowc.m4 \
@@ -86,17 +88,18 @@ am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
 	$(top_srcdir)/gl/m4/off_t.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/strcase.m4 \
-	$(top_srcdir)/gl/m4/strings_h.m4 \
+	$(top_srcdir)/gl/m4/stdlib_h.m4 \
 	$(top_srcdir)/gl/m4/sys_types_h.m4 \
+	$(top_srcdir)/gl/m4/threadlib.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/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/cppunit.m4 \
+	$(top_srcdir)/conf/gcov_valgrind.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) \
@@ -105,60 +108,22 @@ 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_FILES =
 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__uninstall_files_from_dir = { \
-  test -z "$$files" \
-    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
-    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
-         $(am__cd) "$$dir" && rm -f $$files; }; \
-  }
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(testheadersdir)"
-LIBRARIES = $(lib_LIBRARIES)
-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) ResponseBuilder.$(OBJEXT)
-expr_test_OBJECTS = $(am_expr_test_OBJECTS)
-expr_test_DEPENDENCIES = libtest-types.a ../libdapserver.la \
-	../libdapclient.la ../libdap.la
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libd4_ce_parser_la_LIBADD =
+am_libd4_ce_parser_la_OBJECTS =  \
+	libd4_ce_parser_la-D4ConstraintEvaluator.lo \
+	libd4_ce_parser_la-D4FunctionEvaluator.lo \
+	libd4_ce_parser_la-d4_ce_parser.tab.lo \
+	libd4_ce_parser_la-lex.d4_ce.lo \
+	libd4_ce_parser_la-d4_function_parser.tab.lo \
+	libd4_ce_parser_la-lex.d4_function.lo
+libd4_ce_parser_la_OBJECTS = $(am_libd4_ce_parser_la_OBJECTS)
+libd4_ce_parser_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
 DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/conf/depcomp
 am__depfiles_maybe = depfiles
@@ -181,22 +146,44 @@ 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)
+SOURCES = $(libd4_ce_parser_la_SOURCES)
+DIST_SOURCES = $(libd4_ce_parser_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
-HEADERS = $(testheaders_HEADERS)
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(pkgincludedir)"
+HEADERS = $(pkginclude_HEADERS)
 ETAGS = etags
 CTAGS = ctags
-am__tty_colors_dummy = \
-  mgn= red= grn= lgn= blu= brg= std=; \
-  am__color_tests=no
-am__tty_colors = $(am__tty_colors_dummy)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 pkglibexecdir = @pkglibexecdir@
 ACLOCAL = @ACLOCAL@
@@ -250,7 +237,6 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
-EVAL = @EVAL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GLIBC21 = @GLIBC21@
@@ -271,7 +257,6 @@ GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
 GNULIB_FCHDIR = @GNULIB_FCHDIR@
 GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
 GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
-GNULIB_FFS = @GNULIB_FFS@
 GNULIB_FSYNC = @GNULIB_FSYNC@
 GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
 GNULIB_GETCWD = @GNULIB_GETCWD@
@@ -325,6 +310,7 @@ GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
 GNULIB_REALPATH = @GNULIB_REALPATH@
 GNULIB_RMDIR = @GNULIB_RMDIR@
 GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
 GNULIB_SETENV = @GNULIB_SETENV@
 GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
 GNULIB_SETLOCALE = @GNULIB_SETLOCALE@
@@ -397,7 +383,6 @@ HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
 HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
 HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
 HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
-HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
 HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
 HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
 HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
@@ -411,7 +396,6 @@ HAVE_FCHDIR = @HAVE_FCHDIR@
 HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
 HAVE_FDATASYNC = @HAVE_FDATASYNC@
 HAVE_FEATURES_H = @HAVE_FEATURES_H@
-HAVE_FFS = @HAVE_FFS@
 HAVE_FSYNC = @HAVE_FSYNC@
 HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
 HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
@@ -460,6 +444,7 @@ HAVE_READLINK = @HAVE_READLINK@
 HAVE_READLINKAT = @HAVE_READLINKAT@
 HAVE_REALPATH = @HAVE_REALPATH@
 HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
 HAVE_SETENV = @HAVE_SETENV@
 HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
 HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
@@ -467,8 +452,6 @@ 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_STRCASECMP = @HAVE_STRCASECMP@
-HAVE_STRINGS_H = @HAVE_STRINGS_H@
 HAVE_STRTOD = @HAVE_STRTOD@
 HAVE_STRTOLL = @HAVE_STRTOLL@
 HAVE_STRTOULL = @HAVE_STRTOULL@
@@ -485,6 +468,7 @@ HAVE_UNLINKAT = @HAVE_UNLINKAT@
 HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
 HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
 HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_VALGRIND = @HAVE_VALGRIND@
 HAVE_WCHAR_H = @HAVE_WCHAR_H@
 HAVE_WCHAR_T = @HAVE_WCHAR_T@
 HAVE_WCPCPY = @HAVE_WCPCPY@
@@ -539,8 +523,12 @@ LEXLIB = @LEXLIB@
 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
 LIBDAP_VERSION = @LIBDAP_VERSION@
 LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
 LIBS = @LIBS@
+LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -550,7 +538,10 @@ LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
 LOCALE_JA = @LOCALE_JA@
 LOCALE_ZH_CN = @LOCALE_ZH_CN@
 LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -559,7 +550,6 @@ NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_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_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
 NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_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@
@@ -569,7 +559,6 @@ NEXT_LOCALE_H = @NEXT_LOCALE_H@
 NEXT_STDDEF_H = @NEXT_STDDEF_H@
 NEXT_STDINT_H = @NEXT_STDINT_H@
 NEXT_STDLIB_H = @NEXT_STDLIB_H@
-NEXT_STRINGS_H = @NEXT_STRINGS_H@
 NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
 NEXT_UNISTD_H = @NEXT_UNISTD_H@
 NEXT_WCHAR_H = @NEXT_WCHAR_H@
@@ -609,6 +598,7 @@ REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
 REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
 REPLACE_GETCWD = @REPLACE_GETCWD@
 REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
 REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
 REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
 REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
@@ -632,6 +622,7 @@ REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
 REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
 REPLACE_NULL = @REPLACE_NULL@
 REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
 REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
 REPLACE_PUTENV = @REPLACE_PUTENV@
 REPLACE_PWRITE = @REPLACE_PWRITE@
@@ -737,6 +728,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -750,59 +742,60 @@ xmlprivatereq = @xmlprivatereq@
 AUTOMAKE_OPTIONS = foreign
 
 # Arrange to build with the backward compatibility mode enabled.
-AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/GNU $(XML2_CFLAGS) $(CURL_CFLAGS)
-AM_CXXFLAGS = $(am__append_1)
-
-# These are not used by automake but are often useful for certain types of
-# debugging. 
-CXXFLAGS_DEBUG = -g3 -O0  -Wall -W -Wcast-align
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/d4_ce -I$(srcdir) $(XML2_CFLAGS)
+AM_CXXFLAGS = $(am__append_1) $(am__append_2)
+
+# autoconf/automake includes support for yacc and lex so that the input
+# files for those compilers can be listed in a _SOURCES variable and the
+# build will just work. I had a fair amount of hassle getting that going
+# and then realized that cmake might undo all that effort. Also, the
+# changes are not local to this dir only since I'd have to edit the DAP2
+# grammars as well. I've left the edits in a comments although I'm not sure
+# it ever worked correctly. jhrg 10/21/14
+#
+# AM_YFLAGS= -d
+# AM_LFLAGS = -d
+CXXFLAGS_DEBUG = -g3 -O0 -Wall -W -Wcast-align
 TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
-TESTS = DASTest DDSTest 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
-lib_LIBRARIES = libtest-types.a
-libtest_types_a_SOURCES = $(TESTSRCS) $(TEST_HDR)
-testheadersdir = $(pkgincludedir)/test
-testheaders_HEADERS = $(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 ResponseBuilder.cc ResponseBuilder.h
-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 
-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
+noinst_LTLIBRARIES = libd4_ce_parser.la
+pkginclude_HEADERS = D4ConstraintEvaluator.h D4FunctionEvaluator.h
+BUILT_SOURCES = lex.d4_ce.cc lex.d4_function.cc
+# BUILT_SOURCES = d4_ce_parser.hh stack.hh location.hh position.hh d4_function_parser.hh
+libd4_ce_parser_la_SOURCES = D4ConstraintEvaluator.cc \
+	D4ConstraintEvaluator.h D4CEScanner.h D4FunctionEvaluator.cc	\
+	D4FunctionEvaluator.h D4FunctionScanner.h d4_ce_parser.tab.cc	\
+	d4_ce_parser.tab.hh lex.d4_ce.cc d4_function_parser.tab.cc	\
+	d4_function_parser.tab.hh lex.d4_function.cc location.hh	\
+	position.hh stack.hh
+
+
+# d4_ce_parser.yy d4_function_parser.yy d4_ce_scanner.ll d4_function_scanner.ll
+
+# Kludge: If we are not building the scanner/parser from the 
+# grammar sources, make sure to use the scanner class that
+# matches the generated code. This addresses an issue where
+# different versions of flex use 'int' or 'size_t' for some 
+# arguments in the scanner's protected methods. This is not
+# automatically updated to match changes in the gnerated files.
+# jhrg 3/31/15
+#
+# Goog intent behind this idea, but in practice it was not working to
+# build the DAP4 parsers this way. Given more time, it might be
+# something that will work, but for the next release (early April
+# 2015) bison 3.x is going to be a requirement. jhrg 4/5/15
+
+# if !BISON3
+# libd4_ce_parser_la_SOURCES += FlexLexer.h
+# endif 
+libd4_ce_parser_la_CXXFLAGS = $(AM_CPPFLAGS)
+
+# Used by both the "have bison 3+'" and "don't have ..." cases
+GEN_GRAM_SRCS = gen_grammar_sources
+EXTRA_DIST = d4_ce_parser.yy d4_ce_scanner.ll d4_function_parser.yy \
+	d4_function_scanner.ll $(GEN_GRAM_SRCS)
+DISTCLEANFILES = 
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-am
 
 .SUFFIXES:
 .SUFFIXES: .cc .lo .o .obj
@@ -815,9 +808,9 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign d4_ce/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign tests/Makefile
+	  $(AUTOMAKE) --foreign d4_ce/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
@@ -836,61 +829,19 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(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)/$@
-install-libLIBRARIES: $(lib_LIBRARIES)
-	@$(NORMAL_INSTALL)
-	@list='$(lib_LIBRARIES)'; 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 " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
-	  echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \
-	  $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; }
-	@$(POST_INSTALL)
-	@list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \
-	for p in $$list; do \
-	  if test -f $$p; then \
-	    $(am__strip_dir) \
-	    echo " ( cd '$(DESTDIR)$(libdir)' && $(RANLIB) $$f )"; \
-	    ( cd "$(DESTDIR)$(libdir)" && $(RANLIB) $$f ) || exit $$?; \
-	  else :; fi; \
-	done
 
-uninstall-libLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir)
-
-clean-libLIBRARIES:
-	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
-libtest-types.a: $(libtest_types_a_OBJECTS) $(libtest_types_a_DEPENDENCIES) $(EXTRA_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) $(EXTRA_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) $(EXTRA_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) $(EXTRA_expr_test_DEPENDENCIES) 
-	@rm -f expr-test$(EXEEXT)
-	$(CXXLINK) $(expr_test_OBJECTS) $(expr_test_LDADD) $(LIBS)
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+libd4_ce_parser.la: $(libd4_ce_parser_la_OBJECTS) $(libd4_ce_parser_la_DEPENDENCIES) $(EXTRA_libd4_ce_parser_la_DEPENDENCIES) 
+	$(libd4_ce_parser_la_LINK)  $(libd4_ce_parser_la_OBJECTS) $(libd4_ce_parser_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -898,25 +849,12 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ResponseBuilder.Po at am__quote@
- 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@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libd4_ce_parser_la-D4ConstraintEvaluator.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libd4_ce_parser_la-D4FunctionEvaluator.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libd4_ce_parser_la-d4_ce_parser.tab.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libd4_ce_parser_la-d4_function_parser.tab.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libd4_ce_parser_la-lex.d4_ce.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libd4_ce_parser_la-lex.d4_function.Plo at am__quote@
 
 .cc.o:
 @am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -939,32 +877,74 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
 
+libd4_ce_parser_la-D4ConstraintEvaluator.lo: D4ConstraintEvaluator.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -MT libd4_ce_parser_la-D4ConstraintEvaluator.lo -MD -MP -MF $(DEPDIR)/libd4_ce_parser_la-D4ConstraintEvaluator.Tpo -c -o libd4_ce_parser_la-D4ConstraintEvaluator.lo `test -f 'D4ConstraintEvaluator.cc' || echo '$(srcdir)/'`D4ConstraintEvaluator.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libd4_ce_parser_la-D4ConstraintEvaluator.Tpo $(DEPDIR)/libd4_ce_parser_la-D4ConstraintEvaluator.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4ConstraintEvaluator.cc' object='libd4_ce_parser_la-D4ConstraintEvaluator.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -c -o libd4_ce_parser_la-D4ConstraintEvaluator.lo `test -f 'D4ConstraintEvaluator.cc' || echo '$(srcdir)/'`D4ConstraintEvaluator.cc
+
+libd4_ce_parser_la-D4FunctionEvaluator.lo: D4FunctionEvaluator.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -MT libd4_ce_parser_la-D4FunctionEvaluator.lo -MD -MP -MF $(DEPDIR)/libd4_ce_parser_la-D4FunctionEvaluator.Tpo -c -o libd4_ce_parser_la-D4FunctionEvaluator.lo `test -f 'D4FunctionEvaluator.cc' || echo '$(srcdir)/'`D4FunctionEvaluator.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libd4_ce_parser_la-D4FunctionEvaluator.Tpo $(DEPDIR)/libd4_ce_parser_la-D4FunctionEvaluator.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4FunctionEvaluator.cc' object='libd4_ce_parser_la-D4FunctionEvaluator.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -c -o libd4_ce_parser_la-D4FunctionEvaluator.lo `test -f 'D4FunctionEvaluator.cc' || echo '$(srcdir)/'`D4FunctionEvaluator.cc
+
+libd4_ce_parser_la-d4_ce_parser.tab.lo: d4_ce_parser.tab.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -MT libd4_ce_parser_la-d4_ce_parser.tab.lo -MD -MP -MF $(DEPDIR)/libd4_ce_parser_la-d4_ce_parser.tab.Tpo -c -o libd4_ce_parser_la-d4_ce_parser.tab.lo `test -f 'd4_ce_parser.tab.cc' || echo '$(srcdir)/'`d4_ce_parser.tab.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libd4_ce_parser_la-d4_ce_parser.tab.Tpo $(DEPDIR)/libd4_ce_parser_la-d4_ce_parser.tab.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='d4_ce_parser.tab.cc' object='libd4_ce_parser_la-d4_ce_parser.tab.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -c -o libd4_ce_parser_la-d4_ce_parser.tab.lo `test -f 'd4_ce_parser.tab.cc' || echo '$(srcdir)/'`d4_ce_parser.tab.cc
+
+libd4_ce_parser_la-lex.d4_ce.lo: lex.d4_ce.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -MT libd4_ce_parser_la-lex.d4_ce.lo -MD -MP -MF $(DEPDIR)/libd4_ce_parser_la-lex.d4_ce.Tpo -c -o libd4_ce_parser_la-lex.d4_ce.lo `test -f 'lex.d4_ce.cc' || echo '$(srcdir)/'`lex.d4_ce.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libd4_ce_parser_la-lex.d4_ce.Tpo $(DEPDIR)/libd4_ce_parser_la-lex.d4_ce.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='lex.d4_ce.cc' object='libd4_ce_parser_la-lex.d4_ce.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -c -o libd4_ce_parser_la-lex.d4_ce.lo `test -f 'lex.d4_ce.cc' || echo '$(srcdir)/'`lex.d4_ce.cc
+
+libd4_ce_parser_la-d4_function_parser.tab.lo: d4_function_parser.tab.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -MT libd4_ce_parser_la-d4_function_parser.tab.lo -MD -MP -MF $(DEPDIR)/libd4_ce_parser_la-d4_function_parser.tab.Tpo -c -o libd4_ce_parser_la-d4_function_parser.tab.lo `test -f 'd4_function_parser.tab.cc' || echo '$(srcdir)/'`d4_function_parser.tab.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libd4_ce_parser_la-d4_function_parser.tab.Tpo $(DEPDIR)/libd4_ce_parser_la-d4_function_parser.tab.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='d4_function_parser.tab.cc' object='libd4_ce_parser_la-d4_function_parser.tab.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -c -o libd4_ce_parser_la-d4_function_parser.tab.lo `test -f 'd4_function_parser.tab.cc' || echo '$(srcdir)/'`d4_function_parser.tab.cc
+
+libd4_ce_parser_la-lex.d4_function.lo: lex.d4_function.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -MT libd4_ce_parser_la-lex.d4_function.lo -MD -MP -MF $(DEPDIR)/libd4_ce_parser_la-lex.d4_function.Tpo -c -o libd4_ce_parser_la-lex.d4_function.lo `test -f 'lex.d4_function.cc' || echo '$(srcdir)/'`lex.d4_function.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libd4_ce_parser_la-lex.d4_function.Tpo $(DEPDIR)/libd4_ce_parser_la-lex.d4_function.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='lex.d4_function.cc' object='libd4_ce_parser_la-lex.d4_function.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libd4_ce_parser_la_CXXFLAGS) $(CXXFLAGS) -c -o libd4_ce_parser_la-lex.d4_function.lo `test -f 'lex.d4_function.cc' || echo '$(srcdir)/'`lex.d4_function.cc
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
 clean-libtool:
 	-rm -rf .libs _libs
-install-testheadersHEADERS: $(testheaders_HEADERS)
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
 	@$(NORMAL_INSTALL)
-	@list='$(testheaders_HEADERS)'; test -n "$(testheadersdir)" || list=; \
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
 	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(testheadersdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(testheadersdir)" || exit 1; \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
 	fi; \
 	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)$(testheadersdir)'"; \
-	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(testheadersdir)" || exit $$?; \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
 	done
 
-uninstall-testheadersHEADERS:
+uninstall-pkgincludeHEADERS:
 	@$(NORMAL_UNINSTALL)
-	@list='$(testheaders_HEADERS)'; test -n "$(testheadersdir)" || list=; \
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(testheadersdir)'; $(am__uninstall_files_from_dir)
+	dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -1032,99 +1012,6 @@ cscopelist:  $(HEADERS) $(SOURCES) $(LISP)
 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 $(AM_TESTS_FD_REDIRECT); 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 \
-	    col="$$grn"; \
-	  else \
-	    col="$$red"; \
-	  fi; \
-	  echo "$${col}$$dashes$${std}"; \
-	  echo "$${col}$$banner$${std}"; \
-	  test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
-	  test -z "$$report" || echo "$${col}$$report$${std}"; \
-	  echo "$${col}$$dashes$${std}"; \
-	  test "$$failed" -eq 0; \
-	else :; fi
-
 distdir: $(DISTFILES)
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -1156,16 +1043,15 @@ distdir: $(DISTFILES)
 	  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) $(HEADERS)
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
 installdirs:
-	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(testheadersdir)"; do \
+	for dir in "$(DESTDIR)$(pkgincludedir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
-install: install-am
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-am
 install-exec: install-exec-am
 install-data: install-data-am
 uninstall: uninstall-am
@@ -1196,16 +1082,17 @@ distclean-generic:
 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-am
 
-clean-am: clean-checkPROGRAMS clean-generic clean-libLIBRARIES \
-	clean-libtool clean-local mostlyclean-am
+clean-am: clean-generic clean-libtool clean-local \
+	clean-noinstLTLIBRARIES mostlyclean-am
 
 distclean: distclean-am
 	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-local distclean-tags
+	distclean-tags
 
 dvi: dvi-am
 
@@ -1219,13 +1106,13 @@ info: info-am
 
 info-am:
 
-install-data-am: install-testheadersHEADERS
+install-data-am: install-pkgincludeHEADERS
 
 install-dvi: install-dvi-am
 
 install-dvi-am:
 
-install-exec-am: install-libLIBRARIES
+install-exec-am:
 
 install-html: install-html-am
 
@@ -1265,64 +1152,73 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-libLIBRARIES uninstall-testheadersHEADERS
+uninstall-am: uninstall-pkgincludeHEADERS
 
-.MAKE: check-am install-am install-strip
+.MAKE: all check install install-am install-strip
 
-.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
-	clean-checkPROGRAMS clean-generic clean-libLIBRARIES \
-	clean-libtool clean-local cscopelist 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-libLIBRARIES install-man install-pdf install-pdf-am \
-	install-ps install-ps-am install-strip \
-	install-testheadersHEADERS 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 uninstall-libLIBRARIES \
-	uninstall-testheadersHEADERS
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-local clean-noinstLTLIBRARIES cscopelist \
+	ctags 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-pkgincludeHEADERS 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 \
+	uninstall-pkgincludeHEADERS
 
 
-#check-local: check-das check-dds
+clean-local:
+	-rm location.hh position.hh stack.hh d4_ce_parser.tab.cc	\
+d4_ce_parser.tab.hh lex.d4_ce.cc d4_function_parser.tab.cc		\
+d4_function_parser.tab.hh lex.d4_function.cc FlexLexer.h
 
-#check-das: atconfig atlocal $(DASTESTSUITE)
-#	$(SHELL) $(DASTESTSUITE) $(DASTESTSUITEFLAGS)
+# if BISON3
+# If we have bison3+, use it. Otherwise, use files from git.
 
-#check-dds: atconfig atlocal $(DDSTESTSUITE)
-#	$(SHELL) $(DDSTESTSUITE) $(DDSTESTSUITEFLAGS)
+lex.d4_ce.cc: d4_ce_scanner.ll d4_ce_parser.tab.cc d4_ce_parser.tab.hh
+	$(LEX) $(LFLAGS) $<
 
-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'
+d4_ce_parser.tab.hh d4_ce_parser.tab.cc stack.hh location.hh position.hh: d4_ce_parser.yy
+	$(YACC) $(YFLAGS) $<
+
+lex.d4_function.cc: d4_function_scanner.ll d4_function_parser.tab.cc d4_function_parser.tab.hh
+	$(LEX) $(LFLAGS) $<
+
+d4_function_parser.tab.hh d4_function_parser.tab.cc: d4_function_parser.yy
+	$(YACC) $(YFLAGS) $<
+
+# These rules keep the 'tmp' files up-to-date w/o us having to remember
+# to rule a special target when the grammars change. Including the '.hh'
+# in the rule below is a work-around for the 'FlexLexer.h' which is _not_
+# generated and breaks this scheme otherwise. We could list each file
+# by name, each one prefixed with $(GEN_GRA...). jhrg 3/31/15
+# all-local: $(GEN_GRAM_SRCS)/*.cc.tmp $(GEN_GRAM_SRCS)/*.hh.tmp
+
+# $(GEN_GRAM_SRCS)/%.cc.tmp : %.cc
+# 	cp $< $@
+
+# $(GEN_GRAM_SRCS)/%.hh.tmp: %.hh
+# 	cp $< $@
+
+# $(GEN_GRAM_SRCS)/%.h.tmp: %.h
+# 	cp $< $@
+
+# else
+
+# # The brute force way to get the C++ grammar sources for hosts
+# # w/o bison 3
+
+# % :: $(GEN_GRAM_SRCS)/%.tmp
+# 	cp $< $@
+
+# FlexLexer.h: $(GEN_GRAM_SRCS)/FlexLexer.h.tmp
+# 	cp $< $@
+# endif
 
 # 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.
diff --git a/d4_ce/d4_ce_parser.tab.cc b/d4_ce/d4_ce_parser.tab.cc
new file mode 100644
index 0000000..375dccc
--- /dev/null
+++ b/d4_ce/d4_ce_parser.tab.cc
@@ -0,0 +1,1836 @@
+// A Bison parser, made by GNU Bison 3.0.1.
+
+// Skeleton implementation for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+
+// First part of user declarations.
+
+#line 37 "d4_ce_parser.tab.cc" // lalr1.cc:399
+
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
+
+#include "d4_ce_parser.tab.hh"
+
+// User implementation prologue.
+
+#line 51 "d4_ce_parser.tab.cc" // lalr1.cc:407
+// Unqualified %code blocks.
+#line 74 "d4_ce_parser.yy" // lalr1.cc:408
+
+   #include <iostream>
+   #include <cstdlib>
+   #include <fstream>
+   
+   #include "BaseType.h"
+   #include "DMR.h"
+   #include "D4Group.h"
+
+   /* include for all driver functions */
+   #include "D4ConstraintEvaluator.h"
+
+   /* this is silly, but I can't figure out a way around */
+   static int yylex(libdap::D4CEParser::semantic_type *yylval,
+                    libdap::location *loc,
+                    libdap::D4CEScanner  &scanner,
+                    libdap::D4ConstraintEvaluator   &driver);
+
+
+#line 73 "d4_ce_parser.tab.cc" // lalr1.cc:408
+
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> // FIXME: INFRINGES ON USER NAME SPACE.
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
+/* 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).  */
+
+# ifndef YYLLOC_DEFAULT
+#  define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                  \
+      if (N)                                                            \
+        {                                                               \
+          (Current).begin  = YYRHSLOC (Rhs, 1).begin;                   \
+          (Current).end    = YYRHSLOC (Rhs, N).end;                     \
+        }                                                               \
+      else                                                              \
+        {                                                               \
+          (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end;      \
+        }                                                               \
+    while (/*CONSTCOND*/ false)
+# endif
+
+
+// Suppress unused-variable warnings by "using" E.
+#define YYUSE(E) ((void) (E))
+
+// Enable debugging if requested.
+#if YYDEBUG
+
+// A pseudo ostream that takes yydebug_ into account.
+# define YYCDEBUG if (yydebug_) (*yycdebug_)
+
+# define YY_SYMBOL_PRINT(Title, Symbol)         \
+  do {                                          \
+    if (yydebug_)                               \
+    {                                           \
+      *yycdebug_ << Title << ' ';               \
+      yy_print_ (*yycdebug_, Symbol);           \
+      *yycdebug_ << std::endl;                  \
+    }                                           \
+  } while (false)
+
+# define YY_REDUCE_PRINT(Rule)          \
+  do {                                  \
+    if (yydebug_)                       \
+      yy_reduce_print_ (Rule);          \
+  } while (false)
+
+# define YY_STACK_PRINT()               \
+  do {                                  \
+    if (yydebug_)                       \
+      yystack_print_ ();                \
+  } while (false)
+
+#else // !YYDEBUG
+
+# define YYCDEBUG if (false) std::cerr
+# define YY_SYMBOL_PRINT(Title, Symbol)  YYUSE(Symbol)
+# define YY_REDUCE_PRINT(Rule)           static_cast<void>(0)
+# define YY_STACK_PRINT()                static_cast<void>(0)
+
+#endif // !YYDEBUG
+
+#define yyerrok         (yyerrstatus_ = 0)
+#define yyclearin       (yyempty = true)
+
+#define YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
+#define YYRECOVERING()  (!!yyerrstatus_)
+
+#line 35 "d4_ce_parser.yy" // lalr1.cc:474
+namespace libdap {
+#line 159 "d4_ce_parser.tab.cc" // lalr1.cc:474
+
+  /* Return 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.  */
+  std::string
+  D4CEParser::yytnamerr_ (const char *yystr)
+  {
+    if (*yystr == '"')
+      {
+        std::string yyr = "";
+        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:
+              yyr += *yyp;
+              break;
+
+            case '"':
+              return yyr;
+            }
+      do_not_strip_quotes: ;
+      }
+
+    return yystr;
+  }
+
+
+  /// Build a parser object.
+  D4CEParser::D4CEParser (D4CEScanner  &scanner_yyarg, D4ConstraintEvaluator  &driver_yyarg)
+    :
+#if YYDEBUG
+      yydebug_ (false),
+      yycdebug_ (&std::cerr),
+#endif
+      scanner (scanner_yyarg),
+      driver (driver_yyarg)
+  {}
+
+  D4CEParser::~D4CEParser ()
+  {}
+
+
+  /*---------------.
+  | Symbol types.  |
+  `---------------*/
+
+  inline
+  D4CEParser::syntax_error::syntax_error (const location_type& l, const std::string& m)
+    : std::runtime_error (m)
+    , location (l)
+  {}
+
+  // basic_symbol.
+  template <typename Base>
+  inline
+  D4CEParser::basic_symbol<Base>::basic_symbol ()
+    : value ()
+  {}
+
+  template <typename Base>
+  inline
+  D4CEParser::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
+    : Base (other)
+    , value ()
+    , location (other.location)
+  {
+      switch (other.type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.copy< bool > (other.value);
+        break;
+
+      case 38: // index
+        value.copy< libdap::D4ConstraintEvaluator::index > (other.value);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.copy< std::string > (other.value);
+        break;
+
+      default:
+        break;
+    }
+
+  }
+
+
+  template <typename Base>
+  inline
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const semantic_type& v, const location_type& l)
+    : Base (t)
+    , value ()
+    , location (l)
+  {
+    (void) v;
+      switch (this->type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.copy< bool > (v);
+        break;
+
+      case 38: // index
+        value.copy< libdap::D4ConstraintEvaluator::index > (v);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.copy< std::string > (v);
+        break;
+
+      default:
+        break;
+    }
+}
+
+
+  // Implementation of basic_symbol constructor for each type.
+
+  template <typename Base>
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const location_type& l)
+    : Base (t)
+    , value ()
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const bool v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const libdap::D4ConstraintEvaluator::index v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+
+  template <typename Base>
+  inline
+  D4CEParser::basic_symbol<Base>::~basic_symbol ()
+  {
+    // User destructor.
+    symbol_number_type yytype = this->type_get ();
+    switch (yytype)
+    {
+   default:
+      break;
+    }
+
+    // Type destructor.
+    switch (yytype)
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.template destroy< bool > ();
+        break;
+
+      case 38: // index
+        value.template destroy< libdap::D4ConstraintEvaluator::index > ();
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.template destroy< std::string > ();
+        break;
+
+      default:
+        break;
+    }
+
+  }
+
+  template <typename Base>
+  inline
+  void
+  D4CEParser::basic_symbol<Base>::move (basic_symbol& s)
+  {
+    super_type::move(s);
+      switch (this->type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.move< bool > (s.value);
+        break;
+
+      case 38: // index
+        value.move< libdap::D4ConstraintEvaluator::index > (s.value);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.move< std::string > (s.value);
+        break;
+
+      default:
+        break;
+    }
+
+    location = s.location;
+  }
+
+  // by_type.
+  inline
+  D4CEParser::by_type::by_type ()
+     : type (empty)
+  {}
+
+  inline
+  D4CEParser::by_type::by_type (const by_type& other)
+    : type (other.type)
+  {}
+
+  inline
+  D4CEParser::by_type::by_type (token_type t)
+    : type (yytranslate_ (t))
+  {}
+
+  inline
+  void
+  D4CEParser::by_type::move (by_type& that)
+  {
+    type = that.type;
+    that.type = empty;
+  }
+
+  inline
+  int
+  D4CEParser::by_type::type_get () const
+  {
+    return type;
+  }
+  // Implementation of make_symbol for each symbol type.
+  D4CEParser::symbol_type
+  D4CEParser::make_END (const location_type& l)
+  {
+    return symbol_type (token::END, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_WORD (const std::string& v, const location_type& l)
+  {
+    return symbol_type (token::WORD, v, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_STRING (const std::string& v, const location_type& l)
+  {
+    return symbol_type (token::STRING, v, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_SEMICOLON (const location_type& l)
+  {
+    return symbol_type (token::SEMICOLON, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_PIPE (const location_type& l)
+  {
+    return symbol_type (token::PIPE, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LBRACKET (const location_type& l)
+  {
+    return symbol_type (token::LBRACKET, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_RBRACKET (const location_type& l)
+  {
+    return symbol_type (token::RBRACKET, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_COLON (const location_type& l)
+  {
+    return symbol_type (token::COLON, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LBRACE (const location_type& l)
+  {
+    return symbol_type (token::LBRACE, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_RBRACE (const location_type& l)
+  {
+    return symbol_type (token::RBRACE, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_COMMA (const location_type& l)
+  {
+    return symbol_type (token::COMMA, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_ND (const location_type& l)
+  {
+    return symbol_type (token::ND, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_ASSIGN (const location_type& l)
+  {
+    return symbol_type (token::ASSIGN, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LESS (const location_type& l)
+  {
+    return symbol_type (token::LESS, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_GREATER (const location_type& l)
+  {
+    return symbol_type (token::GREATER, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LESS_EQUAL (const location_type& l)
+  {
+    return symbol_type (token::LESS_EQUAL, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_GREATER_EQUAL (const location_type& l)
+  {
+    return symbol_type (token::GREATER_EQUAL, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_EQUAL (const location_type& l)
+  {
+    return symbol_type (token::EQUAL, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_NOT_EQUAL (const location_type& l)
+  {
+    return symbol_type (token::NOT_EQUAL, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_REGEX_MATCH (const location_type& l)
+  {
+    return symbol_type (token::REGEX_MATCH, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LESS_BBOX (const location_type& l)
+  {
+    return symbol_type (token::LESS_BBOX, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_GREATER_BBOX (const location_type& l)
+  {
+    return symbol_type (token::GREATER_BBOX, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_MASK (const location_type& l)
+  {
+    return symbol_type (token::MASK, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_GROUP_SEP (const location_type& l)
+  {
+    return symbol_type (token::GROUP_SEP, l);
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_PATH_SEP (const location_type& l)
+  {
+    return symbol_type (token::PATH_SEP, l);
+  }
+
+
+
+  // by_state.
+  inline
+  D4CEParser::by_state::by_state ()
+    : state (empty)
+  {}
+
+  inline
+  D4CEParser::by_state::by_state (const by_state& other)
+    : state (other.state)
+  {}
+
+  inline
+  void
+  D4CEParser::by_state::move (by_state& that)
+  {
+    state = that.state;
+    that.state = empty;
+  }
+
+  inline
+  D4CEParser::by_state::by_state (state_type s)
+    : state (s)
+  {}
+
+  inline
+  D4CEParser::symbol_number_type
+  D4CEParser::by_state::type_get () const
+  {
+    return state == empty ? 0 : yystos_[state];
+  }
+
+  inline
+  D4CEParser::stack_symbol_type::stack_symbol_type ()
+  {}
+
+
+  inline
+  D4CEParser::stack_symbol_type::stack_symbol_type (state_type s, symbol_type& that)
+    : super_type (s, that.location)
+  {
+      switch (that.type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.move< bool > (that.value);
+        break;
+
+      case 38: // index
+        value.move< libdap::D4ConstraintEvaluator::index > (that.value);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.move< std::string > (that.value);
+        break;
+
+      default:
+        break;
+    }
+
+    // that is emptied.
+    that.type = empty;
+  }
+
+  inline
+  D4CEParser::stack_symbol_type&
+  D4CEParser::stack_symbol_type::operator= (const stack_symbol_type& that)
+  {
+    state = that.state;
+      switch (that.type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.copy< bool > (that.value);
+        break;
+
+      case 38: // index
+        value.copy< libdap::D4ConstraintEvaluator::index > (that.value);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.copy< std::string > (that.value);
+        break;
+
+      default:
+        break;
+    }
+
+    location = that.location;
+    return *this;
+  }
+
+
+  template <typename Base>
+  inline
+  void
+  D4CEParser::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
+  {
+    if (yymsg)
+      YY_SYMBOL_PRINT (yymsg, yysym);
+  }
+
+#if YYDEBUG
+  template <typename Base>
+  void
+  D4CEParser::yy_print_ (std::ostream& yyo,
+                                     const basic_symbol<Base>& yysym) const
+  {
+    std::ostream& yyoutput = yyo;
+    YYUSE (yyoutput);
+    symbol_number_type yytype = yysym.type_get ();
+    yyo << (yytype < yyntokens_ ? "token" : "nterm")
+        << ' ' << yytname_[yytype] << " ("
+        << yysym.location << ": ";
+    YYUSE (yytype);
+    yyo << ')';
+  }
+#endif
+
+  inline
+  void
+  D4CEParser::yypush_ (const char* m, state_type s, symbol_type& sym)
+  {
+    stack_symbol_type t (s, sym);
+    yypush_ (m, t);
+  }
+
+  inline
+  void
+  D4CEParser::yypush_ (const char* m, stack_symbol_type& s)
+  {
+    if (m)
+      YY_SYMBOL_PRINT (m, s);
+    yystack_.push (s);
+  }
+
+  inline
+  void
+  D4CEParser::yypop_ (unsigned int n)
+  {
+    yystack_.pop (n);
+  }
+
+#if YYDEBUG
+  std::ostream&
+  D4CEParser::debug_stream () const
+  {
+    return *yycdebug_;
+  }
+
+  void
+  D4CEParser::set_debug_stream (std::ostream& o)
+  {
+    yycdebug_ = &o;
+  }
+
+
+  D4CEParser::debug_level_type
+  D4CEParser::debug_level () const
+  {
+    return yydebug_;
+  }
+
+  void
+  D4CEParser::set_debug_level (debug_level_type l)
+  {
+    yydebug_ = l;
+  }
+#endif // YYDEBUG
+
+  inline D4CEParser::state_type
+  D4CEParser::yy_lr_goto_state_ (state_type yystate, int yylhs)
+  {
+    int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
+    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+      return yytable_[yyr];
+    else
+      return yydefgoto_[yylhs - yyntokens_];
+  }
+
+  inline bool
+  D4CEParser::yy_pact_value_is_default_ (int yyvalue)
+  {
+    return yyvalue == yypact_ninf_;
+  }
+
+  inline bool
+  D4CEParser::yy_table_value_is_error_ (int yyvalue)
+  {
+    return yyvalue == yytable_ninf_;
+  }
+
+  int
+  D4CEParser::parse ()
+  {
+    /// Whether yyla contains a lookahead.
+    bool yyempty = true;
+
+    // State.
+    int yyn;
+    int yylen = 0;
+
+    // Error handling.
+    int yynerrs_ = 0;
+    int yyerrstatus_ = 0;
+
+    /// The lookahead symbol.
+    symbol_type yyla;
+
+    /// The locations where the error started and ended.
+    stack_symbol_type yyerror_range[3];
+
+    /// $$ and @$.
+    stack_symbol_type yylhs;
+
+    /// The return value of parse ().
+    int yyresult;
+
+    // FIXME: This shoud be completely indented.  It is not yet to
+    // avoid gratuitous conflicts when merging into the master branch.
+    try
+      {
+    YYCDEBUG << "Starting parse" << std::endl;
+
+
+    // User initialization code.
+    #line 66 "d4_ce_parser.yy" // lalr1.cc:727
+{
+    // Initialize the initial location. This is printed when the parser builds
+    // its own error messages - when the parse fails as opposed to when the 
+    // CE names a missing variables, ...
+
+    yyla.location.initialize (driver.expression());
+}
+
+#line 871 "d4_ce_parser.tab.cc" // lalr1.cc:727
+
+    /* Initialize the stack.  The initial state will be set in
+       yynewstate, since the latter expects the semantical and the
+       location values to have been already stored, initialize these
+       stacks with a primary value.  */
+    yystack_.clear ();
+    yypush_ (YY_NULLPTR, 0, yyla);
+
+    // A new symbol was pushed on the stack.
+  yynewstate:
+    YYCDEBUG << "Entering state " << yystack_[0].state << std::endl;
+
+    // Accept?
+    if (yystack_[0].state == yyfinal_)
+      goto yyacceptlab;
+
+    goto yybackup;
+
+    // Backup.
+  yybackup:
+
+    // Try to take a decision without lookahead.
+    yyn = yypact_[yystack_[0].state];
+    if (yy_pact_value_is_default_ (yyn))
+      goto yydefault;
+
+    // Read a lookahead token.
+    if (yyempty)
+      {
+        YYCDEBUG << "Reading a token: ";
+        try
+          {
+            yyla.type = yytranslate_ (yylex (&yyla.value, &yyla.location, scanner, driver));
+          }
+        catch (const syntax_error& yyexc)
+          {
+            error (yyexc);
+            goto yyerrlab1;
+          }
+        yyempty = false;
+      }
+    YY_SYMBOL_PRINT ("Next token is", yyla);
+
+    /* If the proper action on seeing token YYLA.TYPE is to reduce or
+       to detect an error, take that action.  */
+    yyn += yyla.type_get ();
+    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
+      goto yydefault;
+
+    // Reduce or error.
+    yyn = yytable_[yyn];
+    if (yyn <= 0)
+      {
+        if (yy_table_value_is_error_ (yyn))
+          goto yyerrlab;
+        yyn = -yyn;
+        goto yyreduce;
+      }
+
+    // Discard the token being shifted.
+    yyempty = true;
+
+    // Count tokens shifted since error; after three, turn off error status.
+    if (yyerrstatus_)
+      --yyerrstatus_;
+
+    // Shift the lookahead token.
+    yypush_ ("Shifting", yyn, yyla);
+    goto yynewstate;
+
+  /*-----------------------------------------------------------.
+  | yydefault -- do the default action for the current state.  |
+  `-----------------------------------------------------------*/
+  yydefault:
+    yyn = yydefact_[yystack_[0].state];
+    if (yyn == 0)
+      goto yyerrlab;
+    goto yyreduce;
+
+  /*-----------------------------.
+  | yyreduce -- Do a reduction.  |
+  `-----------------------------*/
+  yyreduce:
+    yylen = yyr2_[yyn];
+    yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);
+    /* Variants are always initialized to an empty instance of the
+       correct type. The default $$=$1 action is NOT applied when using
+       variants.  */
+      switch (yyr1_[yyn])
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        yylhs.value.build< bool > ();
+        break;
+
+      case 38: // index
+        yylhs.value.build< libdap::D4ConstraintEvaluator::index > ();
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        yylhs.value.build< std::string > ();
+        break;
+
+      default:
+        break;
+    }
+
+
+    // Compute the default @$.
+    {
+      slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
+      YYLLOC_DEFAULT (yylhs.location, slice, yylen);
+    }
+
+    // Perform the reduction.
+    YY_REDUCE_PRINT (yyn);
+    try
+      {
+        switch (yyn)
+          {
+  case 2:
+#line 141 "d4_ce_parser.yy" // lalr1.cc:847
+    { driver.set_result(yystack_[0].value.as< bool > ()); }
+#line 1007 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 3:
+#line 142 "d4_ce_parser.yy" // lalr1.cc:847
+    { driver.set_result(yystack_[2].value.as< bool > () && yystack_[0].value.as< bool > ()); }
+#line 1013 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 4:
+#line 145 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = yystack_[0].value.as< bool > (); }
+#line 1019 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 5:
+#line 146 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = yystack_[2].value.as< bool > () && yystack_[0].value.as< bool > (); }
+#line 1025 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 6:
+#line 150 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< bool > () = driver.slice_dimension(yystack_[2].value.as< std::string > (), yystack_[0].value.as< libdap::D4ConstraintEvaluator::index > ());
+}
+#line 1033 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 7:
+#line 155 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = yystack_[0].value.as< bool > (); }
+#line 1039 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 8:
+#line 156 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = yystack_[2].value.as< bool > () && yystack_[0].value.as< bool > (); }
+#line 1045 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 9:
+#line 159 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = yystack_[0].value.as< bool > (); }
+#line 1051 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 10:
+#line 160 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = yystack_[2].value.as< bool > () && yystack_[0].value.as< bool > (); }
+#line 1057 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 11:
+#line 165 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var(yystack_[0].value.as< std::string > ());
+    }
+    else {
+        btp = driver.dmr()->root()->find_var(yystack_[0].value.as< std::string > ());
+    }
+    
+    if (!btp)
+        driver.throw_not_found(yystack_[0].value.as< std::string > (), "id");
+
+#if 0    
+    if (btp->type() == dods_array_c)
+        yylhs.value.as< bool > () = driver.mark_variable(btp) && driver.mark_array_variable(btp);   // handle array w/o slice ops
+    else
+#endif
+
+    yylhs.value.as< bool > () = driver.mark_variable(btp);
+}
+#line 1082 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 12:
+#line 187 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var(yystack_[1].value.as< std::string > ());
+    }
+    else {
+        btp = driver.dmr()->root()->find_var(yystack_[1].value.as< std::string > ());
+    }
+    
+    if (!btp)
+        driver.throw_not_found(yystack_[1].value.as< std::string > (), "id indexes");
+        
+    if (btp->type() != dods_array_c)
+        driver.throw_not_array(yystack_[1].value.as< std::string > (), "id indexes");
+        
+    yylhs.value.as< bool > () = driver.mark_variable(btp); //  && driver.mark_array_variable(btp);
+}
+#line 1104 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 13:
+#line 206 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var(yystack_[0].value.as< std::string > ());
+    }
+    else {
+        btp = driver.dmr()->root()->find_var(yystack_[0].value.as< std::string > ());
+    }
+
+    if (!btp)
+        driver.throw_not_found(yystack_[0].value.as< std::string > (), "id fields");
+    
+    if (btp->type() == dods_array_c) {
+        if (btp->var() && !btp->var()->is_constructor_type())
+            throw Error("The variable " + yystack_[0].value.as< std::string > () + " must be a Structure or Sequence to be used with {}.");
+            
+        // This call also tests the btp to make sure it's an array
+        driver.mark_array_variable(btp);
+    }
+    else {
+        // Don't mark the variable here because only some fields are to be sent and those
+        // will be marked when the fields are parsed
+        if (!btp->is_constructor_type())
+            throw Error("The variable " + yystack_[0].value.as< std::string > () + " must be a Structure or Sequence to be used with {}.");
+    }
+    
+    // push the basetype (a ctor or array of ctor) on the stack so that it is
+    // accessible while the fields are being parsed
+    driver.push_basetype(btp);
+}
+#line 1139 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 14:
+#line 237 "d4_ce_parser.yy" // lalr1.cc:847
+    { 
+    driver.pop_basetype(); 
+    yylhs.value.as< bool > () = true; 
+}
+#line 1148 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 15:
+#line 243 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var(yystack_[1].value.as< std::string > ());
+    }
+    else {
+        btp = driver.dmr()->root()->find_var(yystack_[1].value.as< std::string > ());
+    }
+
+    if (!btp)
+        driver.throw_not_found(yystack_[1].value.as< std::string > (), "id indexes fields");
+    
+    if (btp->type() != dods_array_c)
+        driver.throw_not_array(yystack_[1].value.as< std::string > (), "id indexes fields");
+
+    // This call also tests the btp to make sure it's an array
+    driver.mark_array_variable(btp);
+    
+    if (!btp->var()->is_constructor_type())
+        throw Error("The variable " + yystack_[1].value.as< std::string > () + " must be a Structure or Sequence to be used with {}.");
+      
+    driver.push_basetype(btp->var());       
+}
+#line 1176 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 16:
+#line 267 "d4_ce_parser.yy" // lalr1.cc:847
+    { 
+    driver.pop_basetype();
+    yylhs.value.as< bool > () = true; 
+}
+#line 1185 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 17:
+#line 279 "d4_ce_parser.yy" // lalr1.cc:847
+    { 
+    driver.push_index(yystack_[0].value.as< libdap::D4ConstraintEvaluator::index > ()); 
+    yylhs.value.as< bool > () = true; 
+}
+#line 1194 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 18:
+#line 283 "d4_ce_parser.yy" // lalr1.cc:847
+    { driver.push_index(yystack_[0].value.as< libdap::D4ConstraintEvaluator::index > ()); }
+#line 1200 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 19:
+#line 283 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = yystack_[0].value.as< bool > (); }
+#line 1206 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 20:
+#line 286 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(); }
+#line 1212 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 21:
+#line 287 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[1].value.as< std::string > ()); }
+#line 1218 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 22:
+#line 288 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[3].value.as< std::string > (), 1, yystack_[1].value.as< std::string > ()); }
+#line 1224 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 23:
+#line 289 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[5].value.as< std::string > (), yystack_[3].value.as< std::string > (), yystack_[1].value.as< std::string > ()); }
+#line 1230 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 24:
+#line 290 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[2].value.as< std::string > (), 1); }
+#line 1236 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 25:
+#line 291 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[4].value.as< std::string > (), yystack_[2].value.as< std::string > ()); }
+#line 1242 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 26:
+#line 294 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = yystack_[1].value.as< bool > (); }
+#line 1248 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 29:
+#line 311 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = true; }
+#line 1254 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 30:
+#line 312 "d4_ce_parser.yy" // lalr1.cc:847
+    { yylhs.value.as< bool > () = true; }
+#line 1260 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 42:
+#line 334 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > () = yystack_[0].value.as< std::string > ();
+}
+#line 1268 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 43:
+#line 338 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > ().append("/");
+    yylhs.value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+}
+#line 1277 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 44:
+#line 343 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::string > ().append("/");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1287 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 45:
+#line 351 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > ().append("/");
+    yylhs.value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+}
+#line 1296 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 46:
+#line 356 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::string > ().append(".");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1306 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 47:
+#line 364 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > () = yystack_[0].value.as< std::string > ();
+}
+#line 1314 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 48:
+#line 368 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::string > ().append(".");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1324 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 49:
+#line 379 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > ()=yystack_[0].value.as< std::string > ();
+}
+#line 1332 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 50:
+#line 383 "d4_ce_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > ()=yystack_[0].value.as< std::string > ();
+}
+#line 1340 "d4_ce_parser.tab.cc" // lalr1.cc:847
+    break;
+
+
+#line 1344 "d4_ce_parser.tab.cc" // lalr1.cc:847
+          default:
+            break;
+          }
+      }
+    catch (const syntax_error& yyexc)
+      {
+        error (yyexc);
+        YYERROR;
+      }
+    YY_SYMBOL_PRINT ("-> $$ =", yylhs);
+    yypop_ (yylen);
+    yylen = 0;
+    YY_STACK_PRINT ();
+
+    // Shift the result of the reduction.
+    yypush_ (YY_NULLPTR, yylhs);
+    goto yynewstate;
+
+  /*--------------------------------------.
+  | yyerrlab -- here on detecting error.  |
+  `--------------------------------------*/
+  yyerrlab:
+    // If not already recovering from an error, report this error.
+    if (!yyerrstatus_)
+      {
+        ++yynerrs_;
+        error (yyla.location, yysyntax_error_ (yystack_[0].state,
+                                           yyempty ? yyempty_ : yyla.type_get ()));
+      }
+
+
+    yyerror_range[1].location = yyla.location;
+    if (yyerrstatus_ == 3)
+      {
+        /* If just tried and failed to reuse lookahead token after an
+           error, discard it.  */
+
+        // Return failure if at end of input.
+        if (yyla.type_get () == yyeof_)
+          YYABORT;
+        else if (!yyempty)
+          {
+            yy_destroy_ ("Error: discarding", yyla);
+            yyempty = true;
+          }
+      }
+
+    // Else will try to reuse lookahead 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 (false)
+      goto yyerrorlab;
+    yyerror_range[1].location = yystack_[yylen - 1].location;
+    /* $$ was initialized before running the user action.  */
+    YY_SYMBOL_PRINT ("Error: discarding", yylhs);
+    yylhs.~stack_symbol_type();
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYERROR.  */
+    yypop_ (yylen);
+    yylen = 0;
+    goto yyerrlab1;
+
+  /*-------------------------------------------------------------.
+  | yyerrlab1 -- common code for both syntax error and YYERROR.  |
+  `-------------------------------------------------------------*/
+  yyerrlab1:
+    yyerrstatus_ = 3;   // Each real token shifted decrements this.
+    {
+      stack_symbol_type error_token;
+      for (;;)
+        {
+          yyn = yypact_[yystack_[0].state];
+          if (!yy_pact_value_is_default_ (yyn))
+            {
+              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 (yystack_.size () == 1)
+            YYABORT;
+
+          yyerror_range[1].location = yystack_[0].location;
+          yy_destroy_ ("Error: popping", yystack_[0]);
+          yypop_ ();
+          YY_STACK_PRINT ();
+        }
+
+      yyerror_range[2].location = yyla.location;
+      YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);
+
+      // Shift the error token.
+      error_token.state = yyn;
+      yypush_ ("Shifting", error_token);
+    }
+    goto yynewstate;
+
+    // Accept.
+  yyacceptlab:
+    yyresult = 0;
+    goto yyreturn;
+
+    // Abort.
+  yyabortlab:
+    yyresult = 1;
+    goto yyreturn;
+
+  yyreturn:
+    if (!yyempty)
+      yy_destroy_ ("Cleanup: discarding lookahead", yyla);
+
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYABORT or YYACCEPT.  */
+    yypop_ (yylen);
+    while (1 < yystack_.size ())
+      {
+        yy_destroy_ ("Cleanup: popping", yystack_[0]);
+        yypop_ ();
+      }
+
+    return yyresult;
+  }
+    catch (...)
+      {
+        YYCDEBUG << "Exception caught: cleaning lookahead and stack"
+                 << std::endl;
+        // Do not try to display the values of the reclaimed symbols,
+        // as their printer might throw an exception.
+        if (!yyempty)
+          yy_destroy_ (YY_NULLPTR, yyla);
+
+        while (1 < yystack_.size ())
+          {
+            yy_destroy_ (YY_NULLPTR, yystack_[0]);
+            yypop_ ();
+          }
+        throw;
+      }
+  }
+
+  void
+  D4CEParser::error (const syntax_error& yyexc)
+  {
+    error (yyexc.location, yyexc.what());
+  }
+
+  // Generate an error message.
+  std::string
+  D4CEParser::yysyntax_error_ (state_type yystate, symbol_number_type yytoken) const
+  {
+    std::string yyres;
+    // Number of reported tokens (one for the "unexpected", one per
+    // "expected").
+    size_t yycount = 0;
+    // Its maximum.
+    enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+    // Arguments of yyformat.
+    char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+
+    /* There are many possibilities here to consider:
+       - If this state is a consistent state with a default action, then
+         the only way this function was invoked is if the default action
+         is an error action.  In that case, don't check for expected
+         tokens because there are none.
+       - The only way there can be no lookahead present (in yytoken) is
+         if this state is a consistent state with a default action.
+         Thus, detecting the absence of a lookahead is sufficient to
+         determine that there is no unexpected or expected token to
+         report.  In that case, just report a simple "syntax error".
+       - Don't assume there isn't a lookahead just because this state is
+         a consistent state with a default action.  There might have
+         been a previous inconsistent state, consistent state with a
+         non-default action, or user semantic action that manipulated
+         yyla.  (However, yyla is currently not documented for users.)
+       - Of course, the expected token list depends on states to have
+         correct lookahead information, and it depends on the parser not
+         to perform extra reductions after fetching a lookahead from the
+         scanner and before detecting a syntax error.  Thus, state
+         merging (from LALR or IELR) and default reductions corrupt the
+         expected token list.  However, the list is correct for
+         canonical LR with one exception: it will still contain any
+         token that will not be accepted due to an error action in a
+         later state.
+    */
+    if (yytoken != yyempty_)
+      {
+        yyarg[yycount++] = yytname_[yytoken];
+        int yyn = yypact_[yystate];
+        if (!yy_pact_value_is_default_ (yyn))
+          {
+            /* Start YYX at -YYN if negative to avoid negative indexes in
+               YYCHECK.  In other words, skip the first -YYN actions for
+               this state because they are default actions.  */
+            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_;
+            for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+              if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
+                  && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
+                {
+                  if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                    {
+                      yycount = 1;
+                      break;
+                    }
+                  else
+                    yyarg[yycount++] = yytname_[yyx];
+                }
+          }
+      }
+
+    char const* yyformat = YY_NULLPTR;
+    switch (yycount)
+      {
+#define YYCASE_(N, S)                         \
+        case N:                               \
+          yyformat = S;                       \
+        break
+        YYCASE_(0, YY_("syntax error"));
+        YYCASE_(1, YY_("syntax error, unexpected %s"));
+        YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+        YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+        YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+        YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+#undef YYCASE_
+      }
+
+    // Argument number.
+    size_t yyi = 0;
+    for (char const* yyp = yyformat; *yyp; ++yyp)
+      if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
+        {
+          yyres += yytnamerr_ (yyarg[yyi++]);
+          ++yyp;
+        }
+      else
+        yyres += *yyp;
+    return yyres;
+  }
+
+
+  const signed char D4CEParser::yypact_ninf_ = -19;
+
+  const signed char D4CEParser::yytable_ninf_ = -47;
+
+  const signed char
+  D4CEParser::yypact_[] =
+  {
+       2,   -19,   -19,    17,    22,    28,   -19,    43,   -19,    -2,
+      21,    18,    16,   -19,    16,    27,   -19,     2,     2,     2,
+      29,    46,    44,    45,    49,    17,    17,   -19,    43,   -19,
+      34,    47,   -19,    -6,    38,   -19,   -19,     2,   -19,    44,
+      46,    16,    32,   -19,     2,   -19,   -19,   -19,   -19,   -19,
+     -19,   -19,   -19,   -19,   -19,   -19,     2,   -19,    31,    25,
+     -19,   -19,   -19,    -6,    42,   -19,   -19,     2,   -19,    37,
+     -19,    50,   -19,   -19
+  };
+
+  const unsigned char
+  D4CEParser::yydefact_[] =
+  {
+       0,    49,    50,     0,     0,     0,     4,     2,     7,     9,
+      11,     0,    42,    47,    43,    47,     1,     0,     0,     0,
+       0,     0,     0,    12,    17,     0,     0,     5,     3,     8,
+      11,    10,    27,     0,     0,    20,     6,     0,    14,     0,
+       0,    44,    47,    48,     0,    41,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,     0,    21,     0,     0,
+      16,    19,    28,    29,     0,    24,    26,     0,    22,     0,
+      30,     0,    25,    23
+  };
+
+  const signed char
+  D4CEParser::yypgoto_[] =
+  {
+     -19,   -19,   -19,    48,   -14,    51,   -19,   -19,   -19,    20,
+     -19,    40,    23,   -19,    19,     1,   -18,   -19,     4,    -1
+  };
+
+  const signed char
+  D4CEParser::yydefgoto_[] =
+  {
+      -1,     4,     5,     6,     7,     8,     9,    22,    39,    23,
+      40,    24,    38,    31,    32,    56,    10,    11,    12,    13
+  };
+
+  const signed char
+  D4CEParser::yytable_[] =
+  {
+      30,    33,    15,    28,    19,     1,     2,    14,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    30,
+       1,     2,    16,    59,    42,    43,    33,     3,    20,    41,
+      18,   -13,    34,    17,    64,    21,    66,    35,    63,    65,
+      71,    20,    26,    25,   -13,    72,    57,    58,    18,    70,
+      68,    69,   -45,    20,    37,   -15,   -18,   -46,    73,    44,
+      61,    36,    60,    62,    67,    27,     0,     0,     0,    29
+  };
+
+  const signed char
+  D4CEParser::yycheck_[] =
+  {
+      18,    19,     3,    17,     6,     3,     4,     3,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,    23,    24,    37,
+       3,     4,     0,    37,    25,    26,    44,    25,     7,    25,
+       5,    10,     3,     5,     3,    14,    11,     8,    56,     8,
+       3,     7,    26,    25,    10,     8,     8,     9,     5,    67,
+       8,     9,    25,     7,    10,    10,     7,    25,     8,    12,
+      40,    21,    39,    44,    63,    17,    -1,    -1,    -1,    18
+  };
+
+  const unsigned char
+  D4CEParser::yystos_[] =
+  {
+       0,     3,     4,    25,    28,    29,    30,    31,    32,    33,
+      43,    44,    45,    46,    45,    46,     0,     5,     5,     6,
+       7,    14,    34,    36,    38,    25,    26,    30,    31,    32,
+      43,    40,    41,    43,     3,     8,    38,    10,    39,    35,
+      37,    45,    46,    46,    12,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    42,     8,     9,    31,
+      39,    36,    41,    43,     3,     8,    11,    42,     8,     9,
+      43,     3,     8,     8
+  };
+
+  const unsigned char
+  D4CEParser::yyr1_[] =
+  {
+       0,    27,    28,    28,    29,    29,    30,    31,    31,    32,
+      32,    33,    33,    34,    33,    35,    33,    36,    37,    36,
+      38,    38,    38,    38,    38,    38,    39,    40,    40,    41,
+      41,    42,    42,    42,    42,    42,    42,    42,    42,    42,
+      42,    42,    43,    43,    43,    44,    44,    45,    45,    46,
+      46
+  };
+
+  const unsigned char
+  D4CEParser::yyr2_[] =
+  {
+       0,     2,     1,     3,     1,     3,     3,     1,     3,     1,
+       3,     1,     2,     0,     3,     0,     4,     1,     0,     3,
+       2,     3,     5,     7,     4,     6,     3,     1,     3,     3,
+       5,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     2,     3,     2,     3,     1,     3,     1,
+       1
+  };
+
+
+
+  // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+  // First, the terminals, then, starting at \a yyntokens_, nonterminals.
+  const char*
+  const D4CEParser::yytname_[] =
+  {
+  "\"end of file\"", "error", "$undefined", "\"word\"", "\"string\"",
+  "\";\"", "\"|\"", "\"[\"", "\"]\"", "\":\"", "\"{\"", "\"}\"", "\",\"",
+  "\"ND\"", "\"=\"", "\"<\"", "\">\"", "\"<=\"", "\">=\"", "\"==\"",
+  "\"!=\"", "\"~=\"", "\"<<\"", "\">>\"", "\"@=\"", "\"/\"", "\".\"",
+  "$accept", "expression", "dimensions", "dimension", "clauses", "clause",
+  "subset", "$@1", "$@2", "indexes", "$@3", "index", "fields", "filter",
+  "predicate", "op", "id", "group", "path", "name", YY_NULLPTR
+  };
+
+#if YYDEBUG
+  const unsigned short int
+  D4CEParser::yyrline_[] =
+  {
+       0,   141,   141,   142,   145,   146,   149,   155,   156,   159,
+     160,   164,   186,   206,   205,   243,   242,   278,   283,   283,
+     286,   287,   288,   289,   290,   291,   294,   297,   298,   311,
+     312,   317,   318,   319,   320,   321,   322,   323,   325,   326,
+     328,   330,   333,   337,   342,   350,   355,   363,   367,   378,
+     382
+  };
+
+  // Print the state stack on the debug stream.
+  void
+  D4CEParser::yystack_print_ ()
+  {
+    *yycdebug_ << "Stack now";
+    for (stack_type::const_iterator
+           i = yystack_.begin (),
+           i_end = yystack_.end ();
+         i != i_end; ++i)
+      *yycdebug_ << ' ' << i->state;
+    *yycdebug_ << std::endl;
+  }
+
+  // Report on the debug stream that the rule \a yyrule is going to be reduced.
+  void
+  D4CEParser::yy_reduce_print_ (int yyrule)
+  {
+    unsigned int yylno = yyrline_[yyrule];
+    int yynrhs = yyr2_[yyrule];
+    // Print the symbols being reduced, and their result.
+    *yycdebug_ << "Reducing stack by rule " << yyrule - 1
+               << " (line " << yylno << "):" << std::endl;
+    // The symbols being reduced.
+    for (int yyi = 0; yyi < yynrhs; yyi++)
+      YY_SYMBOL_PRINT ("   $" << yyi + 1 << " =",
+                       yystack_[(yynrhs) - (yyi + 1)]);
+  }
+#endif // YYDEBUG
+
+  // Symbol number corresponding to token number t.
+  inline
+  D4CEParser::token_number_type
+  D4CEParser::yytranslate_ (int t)
+  {
+    static
+    const token_number_type
+    translate_table[] =
+    {
+     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,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26
+    };
+    const unsigned int user_token_number_max_ = 281;
+    const token_number_type undef_token_ = 2;
+
+    if (static_cast<int>(t) <= yyeof_)
+      return yyeof_;
+    else if (static_cast<unsigned int> (t) <= user_token_number_max_)
+      return translate_table[t];
+    else
+      return undef_token_;
+  }
+
+#line 35 "d4_ce_parser.yy" // lalr1.cc:1157
+} // libdap
+#line 1813 "d4_ce_parser.tab.cc" // lalr1.cc:1157
+#line 388 "d4_ce_parser.yy" // lalr1.cc:1158
+
+
+// Forward the error to the driver for handling. The location parameter
+// provides the line number and character position of the error.
+void
+libdap::D4CEParser::error(const location_type &l, const std::string &m)
+{
+    driver.error(l, m);
+}
+
+/* include for access to scanner.yylex */
+#include "D4CEScanner.h"
+
+static int yylex(libdap::D4CEParser::semantic_type *yylval,
+                 libdap::location *loc,
+                 libdap::D4CEScanner &scanner,
+                 libdap::D4ConstraintEvaluator &driver)
+{
+    if (driver.trace_scanning())
+        scanner.set_debug(true);
+    
+    return( scanner.yylex(yylval, loc) );
+}
diff --git a/d4_ce/d4_ce_parser.tab.hh b/d4_ce/d4_ce_parser.tab.hh
new file mode 100644
index 0000000..508cf69
--- /dev/null
+++ b/d4_ce/d4_ce_parser.tab.hh
@@ -0,0 +1,783 @@
+// A Bison parser, made by GNU Bison 3.0.1.
+
+// Skeleton interface for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file d4_ce_parser.tab.hh
+ ** Define the libdap::parser class.
+ */
+
+// C++ LALR(1) parser skeleton written by Akim Demaille.
+
+#ifndef YY_YY_D4_CE_PARSER_TAB_HH_INCLUDED
+# define YY_YY_D4_CE_PARSER_TAB_HH_INCLUDED
+// //                    "%code requires" blocks.
+#line 48 "d4_ce_parser.yy" // lalr1.cc:372
+
+#include "D4ConstraintEvaluator.h"
+namespace libdap {
+    class D4CEScanner;
+}
+
+
+#line 52 "d4_ce_parser.tab.hh" // lalr1.cc:372
+
+# include <cassert>
+# include <vector>
+# include <iostream>
+# include <stdexcept>
+# include <string>
+# include "stack.hh"
+# include "location.hh"
+#include <typeinfo>
+#ifndef YYASSERT
+# include <cassert>
+# define YYASSERT assert
+#endif
+
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# 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
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+
+#line 35 "d4_ce_parser.yy" // lalr1.cc:372
+namespace libdap {
+#line 128 "d4_ce_parser.tab.hh" // lalr1.cc:372
+
+
+
+  /// A char[S] buffer to store and retrieve objects.
+  ///
+  /// Sort of a variant, but does not keep track of the nature
+  /// of the stored data, since that knowledge is available
+  /// via the current state.
+  template <size_t S>
+  struct variant
+  {
+    /// Type of *this.
+    typedef variant<S> self_type;
+
+    /// Empty construction.
+    variant ()
+      : yytname_ (YY_NULLPTR)
+    {}
+
+    /// Construct and fill.
+    template <typename T>
+    variant (const T& t)
+      : yytname_ (typeid (T).name ())
+    {
+      YYASSERT (sizeof (T) <= S);
+      new (yyas_<T> ()) T (t);
+    }
+
+    /// Destruction, allowed only if empty.
+    ~variant ()
+    {
+      YYASSERT (!yytname_);
+    }
+
+    /// Instantiate an empty \a T in here.
+    template <typename T>
+    T&
+    build ()
+    {
+      YYASSERT (!yytname_);
+      YYASSERT (sizeof (T) <= S);
+      yytname_ = typeid (T).name ();
+      return *new (yyas_<T> ()) T;
+    }
+
+    /// Instantiate a \a T in here from \a t.
+    template <typename T>
+    T&
+    build (const T& t)
+    {
+      YYASSERT (!yytname_);
+      YYASSERT (sizeof (T) <= S);
+      yytname_ = typeid (T).name ();
+      return *new (yyas_<T> ()) T (t);
+    }
+
+    /// Accessor to a built \a T.
+    template <typename T>
+    T&
+    as ()
+    {
+      YYASSERT (yytname_ == typeid (T).name ());
+      YYASSERT (sizeof (T) <= S);
+      return *yyas_<T> ();
+    }
+
+    /// Const accessor to a built \a T (for %printer).
+    template <typename T>
+    const T&
+    as () const
+    {
+      YYASSERT (yytname_ == typeid (T).name ());
+      YYASSERT (sizeof (T) <= S);
+      return *yyas_<T> ();
+    }
+
+    /// Swap the content with \a other, of same type.
+    ///
+    /// Both variants must be built beforehand, because swapping the actual
+    /// data requires reading it (with as()), and this is not possible on
+    /// unconstructed variants: it would require some dynamic testing, which
+    /// should not be the variant's responsability.
+    /// Swapping between built and (possibly) non-built is done with
+    /// variant::move ().
+    template <typename T>
+    void
+    swap (self_type& other)
+    {
+      YYASSERT (yytname_);
+      YYASSERT (yytname_ == other.yytname_);
+      std::swap (as<T> (), other.as<T> ());
+    }
+
+    /// Move the content of \a other to this.
+    ///
+    /// Destroys \a other.
+    template <typename T>
+    void
+    move (self_type& other)
+    {
+      build<T> ();
+      swap<T> (other);
+      other.destroy<T> ();
+    }
+
+    /// Copy the content of \a other to this.
+    template <typename T>
+    void
+    copy (const self_type& other)
+    {
+      build<T> (other.as<T> ());
+    }
+
+    /// Destroy the stored \a T.
+    template <typename T>
+    void
+    destroy ()
+    {
+      as<T> ().~T ();
+      yytname_ = YY_NULLPTR;
+    }
+
+  private:
+    /// Prohibit blind copies.
+    self_type& operator=(const self_type&);
+    variant (const self_type&);
+
+    /// Accessor to raw memory as \a T.
+    template <typename T>
+    T*
+    yyas_ ()
+    {
+      void *yyp = yybuffer_.yyraw;
+      return static_cast<T*> (yyp);
+     }
+
+    /// Const accessor to raw memory as \a T.
+    template <typename T>
+    const T*
+    yyas_ () const
+    {
+      const void *yyp = yybuffer_.yyraw;
+      return static_cast<const T*> (yyp);
+     }
+
+    union
+    {
+      /// Strongest alignment constraints.
+      long double yyalign_me;
+      /// A buffer large enough to store any of the semantic values.
+      char yyraw[S];
+    } yybuffer_;
+
+    /// Whether the content is built: if defined, the name of the stored type.
+    const char *yytname_;
+  };
+
+
+  /// A Bison parser.
+  class D4CEParser
+  {
+  public:
+#ifndef YYSTYPE
+    /// An auxiliary type to compute the largest semantic type.
+    union union_type
+    {
+      // dimensions
+      // dimension
+      // clauses
+      // clause
+      // subset
+      // indexes
+      // fields
+      // filter
+      // predicate
+      char dummy1[sizeof(bool)];
+
+      // index
+      char dummy2[sizeof(libdap::D4ConstraintEvaluator::index)];
+
+      // "word"
+      // "string"
+      // id
+      // group
+      // path
+      // name
+      char dummy3[sizeof(std::string)];
+};
+
+    /// Symbol semantic values.
+    typedef variant<sizeof(union_type)> semantic_type;
+#else
+    typedef YYSTYPE semantic_type;
+#endif
+    /// Symbol locations.
+    typedef location location_type;
+
+    /// Syntax errors thrown from user actions.
+    struct syntax_error : std::runtime_error
+    {
+      syntax_error (const location_type& l, const std::string& m);
+      location_type location;
+    };
+
+    /// Tokens.
+    struct token
+    {
+      enum yytokentype
+      {
+        END = 0,
+        WORD = 258,
+        STRING = 259,
+        SEMICOLON = 260,
+        PIPE = 261,
+        LBRACKET = 262,
+        RBRACKET = 263,
+        COLON = 264,
+        LBRACE = 265,
+        RBRACE = 266,
+        COMMA = 267,
+        ND = 268,
+        ASSIGN = 269,
+        LESS = 270,
+        GREATER = 271,
+        LESS_EQUAL = 272,
+        GREATER_EQUAL = 273,
+        EQUAL = 274,
+        NOT_EQUAL = 275,
+        REGEX_MATCH = 276,
+        LESS_BBOX = 277,
+        GREATER_BBOX = 278,
+        MASK = 279,
+        GROUP_SEP = 280,
+        PATH_SEP = 281
+      };
+    };
+
+    /// (External) token type, as returned by yylex.
+    typedef token::yytokentype token_type;
+
+    /// Internal symbol number.
+    typedef int symbol_number_type;
+
+    /// Internal symbol number for tokens (subsumed by symbol_number_type).
+    typedef unsigned char token_number_type;
+
+    /// A complete symbol.
+    ///
+    /// Expects its Base type to provide access to the symbol type
+    /// via type_get().
+    ///
+    /// Provide access to semantic value and location.
+    template <typename Base>
+    struct basic_symbol : Base
+    {
+      /// Alias to Base.
+      typedef Base super_type;
+
+      /// Default constructor.
+      basic_symbol ();
+
+      /// Copy constructor.
+      basic_symbol (const basic_symbol& other);
+
+      /// Constructor for valueless symbols, and symbols from each type.
+
+  basic_symbol (typename Base::kind_type t, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const bool v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const libdap::D4ConstraintEvaluator::index v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l);
+
+
+      /// Constructor for symbols with semantic value.
+      basic_symbol (typename Base::kind_type t,
+                    const semantic_type& v,
+                    const location_type& l);
+
+      ~basic_symbol ();
+
+      /// Destructive move, \a s is emptied into this.
+      void move (basic_symbol& s);
+
+      /// The semantic value.
+      semantic_type value;
+
+      /// The location.
+      location_type location;
+
+    private:
+      /// Assignment operator.
+      basic_symbol& operator= (const basic_symbol& other);
+    };
+
+    /// Type access provider for token (enum) based symbols.
+    struct by_type
+    {
+      /// Default constructor.
+      by_type ();
+
+      /// Copy constructor.
+      by_type (const by_type& other);
+
+      /// The symbol type as needed by the constructor.
+      typedef token_type kind_type;
+
+      /// Constructor from (external) token numbers.
+      by_type (kind_type t);
+
+      /// Steal the symbol type from \a that.
+      void move (by_type& that);
+
+      /// The (internal) type number (corresponding to \a type).
+      /// -1 when this symbol is empty.
+      symbol_number_type type_get () const;
+
+      /// The token.
+      token_type token () const;
+
+      enum { empty = 0 };
+
+      /// The symbol type.
+      /// -1 when this symbol is empty.
+      token_number_type type;
+    };
+
+    /// "External" symbols: returned by the scanner.
+    typedef basic_symbol<by_type> symbol_type;
+
+    // Symbol constructors declarations.
+    static inline
+    symbol_type
+    make_END (const location_type& l);
+
+    static inline
+    symbol_type
+    make_WORD (const std::string& v, const location_type& l);
+
+    static inline
+    symbol_type
+    make_STRING (const std::string& v, const location_type& l);
+
+    static inline
+    symbol_type
+    make_SEMICOLON (const location_type& l);
+
+    static inline
+    symbol_type
+    make_PIPE (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LBRACKET (const location_type& l);
+
+    static inline
+    symbol_type
+    make_RBRACKET (const location_type& l);
+
+    static inline
+    symbol_type
+    make_COLON (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LBRACE (const location_type& l);
+
+    static inline
+    symbol_type
+    make_RBRACE (const location_type& l);
+
+    static inline
+    symbol_type
+    make_COMMA (const location_type& l);
+
+    static inline
+    symbol_type
+    make_ND (const location_type& l);
+
+    static inline
+    symbol_type
+    make_ASSIGN (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LESS (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GREATER (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LESS_EQUAL (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GREATER_EQUAL (const location_type& l);
+
+    static inline
+    symbol_type
+    make_EQUAL (const location_type& l);
+
+    static inline
+    symbol_type
+    make_NOT_EQUAL (const location_type& l);
+
+    static inline
+    symbol_type
+    make_REGEX_MATCH (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LESS_BBOX (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GREATER_BBOX (const location_type& l);
+
+    static inline
+    symbol_type
+    make_MASK (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GROUP_SEP (const location_type& l);
+
+    static inline
+    symbol_type
+    make_PATH_SEP (const location_type& l);
+
+
+    /// Build a parser object.
+    D4CEParser (D4CEScanner  &scanner_yyarg, D4ConstraintEvaluator  &driver_yyarg);
+    virtual ~D4CEParser ();
+
+    /// Parse.
+    /// \returns  0 iff parsing succeeded.
+    virtual int parse ();
+
+#if YYDEBUG
+    /// The current debugging stream.
+    std::ostream& debug_stream () const YY_ATTRIBUTE_PURE;
+    /// Set the current debugging stream.
+    void set_debug_stream (std::ostream &);
+
+    /// Type for debugging levels.
+    typedef int debug_level_type;
+    /// The current debugging level.
+    debug_level_type debug_level () const YY_ATTRIBUTE_PURE;
+    /// Set the current debugging level.
+    void set_debug_level (debug_level_type l);
+#endif
+
+    /// Report a syntax error.
+    /// \param loc    where the syntax error is found.
+    /// \param msg    a description of the syntax error.
+    virtual void error (const location_type& loc, const std::string& msg);
+
+    /// Report a syntax error.
+    void error (const syntax_error& err);
+
+  private:
+    /// This class is not copyable.
+    D4CEParser (const D4CEParser&);
+    D4CEParser& operator= (const D4CEParser&);
+
+    /// State numbers.
+    typedef int state_type;
+
+    /// Generate an error message.
+    /// \param yystate   the state where the error occurred.
+    /// \param yytoken   the lookahead token type, or yyempty_.
+    virtual std::string yysyntax_error_ (state_type yystate,
+                                         symbol_number_type yytoken) const;
+
+    /// Compute post-reduction state.
+    /// \param yystate   the current state
+    /// \param yylhs     the nonterminal to push on the stack
+    state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
+
+    /// Whether the given \c yypact_ value indicates a defaulted state.
+    /// \param yyvalue   the value to check
+    static bool yy_pact_value_is_default_ (int yyvalue);
+
+    /// Whether the given \c yytable_ value indicates a syntax error.
+    /// \param yyvalue   the value to check
+    static bool yy_table_value_is_error_ (int yyvalue);
+
+    static const signed char yypact_ninf_;
+    static const signed char yytable_ninf_;
+
+    /// Convert a scanner token number \a t to a symbol number.
+    static token_number_type yytranslate_ (int t);
+
+    // Tables.
+  // YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+  // STATE-NUM.
+  static const signed char yypact_[];
+
+  // YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+  // Performed when YYTABLE does not specify something else to do.  Zero
+  // means the default is an error.
+  static const unsigned char yydefact_[];
+
+  // YYPGOTO[NTERM-NUM].
+  static const signed char yypgoto_[];
+
+  // YYDEFGOTO[NTERM-NUM].
+  static const signed char yydefgoto_[];
+
+  // YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+  // positive, shift that token.  If negative, reduce the rule whose
+  // number is the opposite.  If YYTABLE_NINF, syntax error.
+  static const signed char yytable_[];
+
+  static const signed char yycheck_[];
+
+  // YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+  // symbol of state STATE-NUM.
+  static const unsigned char yystos_[];
+
+  // YYR1[YYN] -- Symbol number of symbol that rule YYN derives.
+  static const unsigned char yyr1_[];
+
+  // YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.
+  static const unsigned char yyr2_[];
+
+
+    /// Convert the symbol name \a n to a form suitable for a diagnostic.
+    static std::string yytnamerr_ (const char *n);
+
+
+    /// For a symbol, its name in clear.
+    static const char* const yytname_[];
+#if YYDEBUG
+  // YYRLINE[YYN] -- Source line where rule number YYN was defined.
+  static const unsigned short int yyrline_[];
+    /// Report on the debug stream that the rule \a r is going to be reduced.
+    virtual void yy_reduce_print_ (int r);
+    /// Print the state stack on the debug stream.
+    virtual void yystack_print_ ();
+
+    // Debugging.
+    int yydebug_;
+    std::ostream* yycdebug_;
+
+    /// \brief Display a symbol type, value and location.
+    /// \param yyo    The output stream.
+    /// \param yysym  The symbol.
+    template <typename Base>
+    void yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const;
+#endif
+
+    /// \brief Reclaim the memory associated to a symbol.
+    /// \param yymsg     Why this token is reclaimed.
+    ///                  If null, print nothing.
+    /// \param yysym     The symbol.
+    template <typename Base>
+    void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
+
+  private:
+    /// Type access provider for state based symbols.
+    struct by_state
+    {
+      /// Default constructor.
+      by_state ();
+
+      /// The symbol type as needed by the constructor.
+      typedef state_type kind_type;
+
+      /// Constructor.
+      by_state (kind_type s);
+
+      /// Copy constructor.
+      by_state (const by_state& other);
+
+      /// Steal the symbol type from \a that.
+      void move (by_state& that);
+
+      /// The (internal) type number (corresponding to \a state).
+      /// "empty" when empty.
+      symbol_number_type type_get () const;
+
+      enum { empty = 0 };
+
+      /// The state.
+      state_type state;
+    };
+
+    /// "Internal" symbol: element of the stack.
+    struct stack_symbol_type : basic_symbol<by_state>
+    {
+      /// Superclass.
+      typedef basic_symbol<by_state> super_type;
+      /// Construct an empty symbol.
+      stack_symbol_type ();
+      /// Steal the contents from \a sym to build this.
+      stack_symbol_type (state_type s, symbol_type& sym);
+      /// Assignment, needed by push_back.
+      stack_symbol_type& operator= (const stack_symbol_type& that);
+    };
+
+    /// Stack type.
+    typedef stack<stack_symbol_type> stack_type;
+
+    /// The stack.
+    stack_type yystack_;
+
+    /// Push a new state on the stack.
+    /// \param m    a debug message to display
+    ///             if null, no trace is output.
+    /// \param s    the symbol
+    /// \warning the contents of \a s.value is stolen.
+    void yypush_ (const char* m, stack_symbol_type& s);
+
+    /// Push a new look ahead token on the state on the stack.
+    /// \param m    a debug message to display
+    ///             if null, no trace is output.
+    /// \param s    the state
+    /// \param sym  the symbol (for its value and location).
+    /// \warning the contents of \a s.value is stolen.
+    void yypush_ (const char* m, state_type s, symbol_type& sym);
+
+    /// Pop \a n symbols the three stacks.
+    void yypop_ (unsigned int n = 1);
+
+    // Constants.
+    enum
+    {
+      yyeof_ = 0,
+      yylast_ = 69,     ///< Last index in yytable_.
+      yynnts_ = 20,  ///< Number of nonterminal symbols.
+      yyempty_ = -2,
+      yyfinal_ = 16, ///< Termination state number.
+      yyterror_ = 1,
+      yyerrcode_ = 256,
+      yyntokens_ = 27  ///< Number of tokens.
+    };
+
+
+    // User arguments.
+    D4CEScanner  &scanner;
+    D4ConstraintEvaluator  &driver;
+  };
+
+
+#line 35 "d4_ce_parser.yy" // lalr1.cc:372
+} // libdap
+#line 779 "d4_ce_parser.tab.hh" // lalr1.cc:372
+
+
+
+
+#endif // !YY_YY_D4_CE_PARSER_TAB_HH_INCLUDED
diff --git a/d4_ce/d4_ce_parser.yy b/d4_ce/d4_ce_parser.yy
new file mode 100644
index 0000000..6aa437e
--- /dev/null
+++ b/d4_ce/d4_ce_parser.yy
@@ -0,0 +1,410 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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.
+
+// A minor edit
+
+%skeleton "lalr1.cc" /* -*- C++ -*- */
+%require "2.5"
+%defines
+
+// The d4ce_parser.tab.cc and .hh files define and declare this class
+%define parser_class_name {D4CEParser}
+// D4CEParser is in this namespace
+%define api.namespace {libdap}
+
+%define parse.trace
+%define parse.error verbose
+%define parse.assert
+
+// Could not get this to work with a C++ scanner built by flex. 8/10/13 jhrg
+// %define api.token.constructor
+%define api.value.type variant
+
+// Because the code uses the C++ mode of flex, we don't use this. 8/8/13 jhrg
+// %define api.prefix { d4_ce }
+
+%code requires {
+#include "D4ConstraintEvaluator.h"
+namespace libdap {
+    class D4CEScanner;
+}
+
+}
+
+// Pass both the scanner and parser objects to both the automatically generated
+// parser and scanner.
+%lex-param   { D4CEScanner  &scanner  }
+%parse-param { D4CEScanner  &scanner  }
+
+%lex-param   { D4ConstraintEvaluator  &driver  }
+%parse-param { D4ConstraintEvaluator  &driver  }
+
+%locations
+%initial-action
+{
+    // Initialize the initial location. This is printed when the parser builds
+    // its own error messages - when the parse fails as opposed to when the 
+    // CE names a missing variables, ...
+
+    @$.initialize (driver.expression());
+};
+
+%code {
+   #include <iostream>
+   #include <cstdlib>
+   #include <fstream>
+   
+   #include "BaseType.h"
+   #include "DMR.h"
+   #include "D4Group.h"
+
+   /* include for all driver functions */
+   #include "D4ConstraintEvaluator.h"
+
+   /* this is silly, but I can't figure out a way around */
+   static int yylex(libdap::D4CEParser::semantic_type *yylval,
+                    libdap::location *loc,
+                    libdap::D4CEScanner  &scanner,
+                    libdap::D4ConstraintEvaluator   &driver);
+
+}
+
+// The strings used in the token definitions are used for error messages
+%token <std::string> WORD "word"
+%token <std::string> STRING "string"
+
+%type <bool> predicate filter fields indexes subset clause clauses dimension dimensions
+%type <std::string> id path group name
+%type <libdap::D4ConstraintEvaluator::index> index
+
+%token 
+    END  0  "end of file"
+    
+    SEMICOLON ";"
+    PIPE "|"
+
+    LBRACKET "["
+    RBRACKET "]"
+    COLON ":"
+
+    LBRACE "{"
+    RBRACE "}"
+
+    COMMA ","
+
+    ND "ND"
+    ASSIGN "="
+
+    LESS "<"
+    GREATER ">"
+    LESS_EQUAL "<="
+    GREATER_EQUAL ">="
+    EQUAL "=="
+    NOT_EQUAL "!="
+    REGEX_MATCH "~="
+
+    LESS_BBOX "<<"
+    GREATER_BBOX ">>"
+
+    MASK "@="
+
+    GROUP_SEP "/"
+    PATH_SEP "."
+;
+
+%%
+
+%start expression;
+
+expression : clauses { driver.set_result($1); }
+| dimensions ";" clauses { driver.set_result($1 && $3); }
+;
+
+dimensions : dimension { $$ = $1; }
+| dimensions ";" dimension { $$ = $1 && $3; }
+;
+
+dimension : id "=" index
+{
+    $$ = driver.slice_dimension($1, $3);
+}
+;
+
+clauses : clause { $$ = $1; }
+| clauses ";" clause { $$ = $1 && $3; }
+;
+                    
+clause : subset { $$ = $1; }
+| subset "|" filter { $$ = $1 && $3; }
+;
+
+// mark_variable returns a BaseType* or throws Error
+subset : id 
+{
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var($1);
+    }
+    else {
+        btp = driver.dmr()->root()->find_var($1);
+    }
+    
+    if (!btp)
+        driver.throw_not_found($1, "id");
+
+#if 0    
+    if (btp->type() == dods_array_c)
+        $$ = driver.mark_variable(btp) && driver.mark_array_variable(btp);   // handle array w/o slice ops
+    else
+#endif
+
+    $$ = driver.mark_variable(btp);
+}
+
+| id indexes 
+{
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var($1);
+    }
+    else {
+        btp = driver.dmr()->root()->find_var($1);
+    }
+    
+    if (!btp)
+        driver.throw_not_found($1, "id indexes");
+        
+    if (btp->type() != dods_array_c)
+        driver.throw_not_array($1, "id indexes");
+        
+    $$ = driver.mark_variable(btp); //  && driver.mark_array_variable(btp);
+}
+
+| id 
+{
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var($1);
+    }
+    else {
+        btp = driver.dmr()->root()->find_var($1);
+    }
+
+    if (!btp)
+        driver.throw_not_found($1, "id fields");
+    
+    if (btp->type() == dods_array_c) {
+        if (btp->var() && !btp->var()->is_constructor_type())
+            throw Error("The variable " + $1 + " must be a Structure or Sequence to be used with {}.");
+            
+        // This call also tests the btp to make sure it's an array
+        driver.mark_array_variable(btp);
+    }
+    else {
+        // Don't mark the variable here because only some fields are to be sent and those
+        // will be marked when the fields are parsed
+        if (!btp->is_constructor_type())
+            throw Error("The variable " + $1 + " must be a Structure or Sequence to be used with {}.");
+    }
+    
+    // push the basetype (a ctor or array of ctor) on the stack so that it is
+    // accessible while the fields are being parsed
+    driver.push_basetype(btp);
+} 
+fields 
+{ 
+    driver.pop_basetype(); 
+    $$ = true; 
+}
+
+| id indexes
+{
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var($1);
+    }
+    else {
+        btp = driver.dmr()->root()->find_var($1);
+    }
+
+    if (!btp)
+        driver.throw_not_found($1, "id indexes fields");
+    
+    if (btp->type() != dods_array_c)
+        driver.throw_not_array($1, "id indexes fields");
+
+    // This call also tests the btp to make sure it's an array
+    driver.mark_array_variable(btp);
+    
+    if (!btp->var()->is_constructor_type())
+        throw Error("The variable " + $1 + " must be a Structure or Sequence to be used with {}.");
+      
+    driver.push_basetype(btp->var());       
+} 
+fields 
+{ 
+    driver.pop_basetype();
+    $$ = true; 
+}
+
+
+// The following has be removed from the syntax
+// | fields indexes { $$ = true; }
+;
+
+// push_index stores the index in the D4ConstraintEvaluator
+indexes : index 
+{ 
+    driver.push_index($1); 
+    $$ = true; 
+}
+| index { driver.push_index($1); } indexes { $$ = $3; }
+;
+   
+index   : "[" "]" { $$ = driver.make_index(); }
+| "[" WORD "]" { $$ = driver.make_index($2); }
+| "[" WORD ":" WORD "]" { $$ = driver.make_index($2, 1, $4); }
+| "[" WORD ":" WORD ":" WORD "]" { $$ = driver.make_index($2, $4, $6); }
+| "[" WORD ":" "]" { $$ = driver.make_index($2, 1); }
+| "[" WORD ":" WORD ":" "]" { $$ = driver.make_index($2, $4); }
+;
+        
+fields : "{" clauses "}" { $$ = $2; }
+;
+
+filter : predicate 
+| filter "," predicate
+;
+
+// Here we use a grammar that is overly general: id op id is not really
+// supported by the CE evaluator. However, id op constant, which captures
+// the intent of the evaluator design introduces a number of reduce/reduce
+// conflicts because any sensible definition of 'constant' will be the
+// same as the definition of 'name'. This happens because we must make 'name'
+// far more general than ideal (it must include tokens that start with digits
+// odd characters that clash with the operators, et cetera). Note that the
+// actions here must test for id == "ND" and op == "=", along with a host
+// of other checks.
+
+predicate : id op id { $$ = true; }
+          | id op id op id { $$ = true; }
+;
+
+//           | "ND" "=" id { $$ = true; }
+
+op : "<"
+   | ">"
+   | "<="
+   | ">="
+   | "=="
+   | "!="
+   | "~="
+
+   | "<<"
+   | ">>"
+
+   | "@="
+   
+   | "="
+;
+
+id : path
+{
+    $$ = $1;
+}
+| "/" path
+{
+    $$.append("/");
+    $$.append($2);
+}
+| group "/" path
+{
+    $1.append("/");
+    $1.append($3);
+    $$ = $1;
+}
+;
+
+group : "/" name
+{
+    $$.append("/");
+    $$.append($2);
+}
+| group "/" name
+{
+    $1.append(".");
+    $1.append($3);
+    $$ = $1;
+}
+;
+
+path : name 
+{
+    $$ = $1;
+}
+| path "." name
+{
+    $1.append(".");
+    $1.append($3);
+    $$ = $1;
+}
+;
+
+// Because some formats/datasets allow 'any' name for a variable, it's possible
+// that a variable name will be a number, etc. The grammar also allows STRING
+// to support "name"."name with spaces and dots (.)".x
+name : WORD 
+{
+    $$=$1;
+}
+| STRING 
+{
+    $$=$1;
+}
+;
+
+%%
+
+// Forward the error to the driver for handling. The location parameter
+// provides the line number and character position of the error.
+void
+libdap::D4CEParser::error(const location_type &l, const std::string &m)
+{
+    driver.error(l, m);
+}
+
+/* include for access to scanner.yylex */
+#include "D4CEScanner.h"
+
+static int yylex(libdap::D4CEParser::semantic_type *yylval,
+                 libdap::location *loc,
+                 libdap::D4CEScanner &scanner,
+                 libdap::D4ConstraintEvaluator &driver)
+{
+    if (driver.trace_scanning())
+        scanner.set_debug(true);
+    
+    return( scanner.yylex(yylval, loc) );
+}
diff --git a/d4_ce/d4_ce_scanner.ll b/d4_ce/d4_ce_scanner.ll
new file mode 100644
index 0000000..04c9aaf
--- /dev/null
+++ b/d4_ce/d4_ce_scanner.ll
@@ -0,0 +1,158 @@
+
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2013 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++ -*- */
+//#include "config.h"
+
+#include <string>
+
+#include "D4CEScanner.h"
+
+/* typedef to make the returns for the tokens shorter */
+typedef libdap::D4CEParser::token token;
+
+/* This was added because of some notes on the net about compiler version
+   issues. I don't know if it's needed when using the C++ mode of flex. */
+#undef yywrap
+#define yywrap() 1
+
+/* define yyterminate as this instead of NULL */
+#define yyterminate() return(token::END)
+
+%}
+
+%option c++
+%option yyclass="D4CEScanner"
+
+/* Use this if several scanners are needed. This will cause flex to
+   #define yyFlexLexer to be <prefix>FlexLexer (the yyFlexLexer is defined
+   in lex.<prefix>.cc. jhrg 8/8/13 */
+%option prefix="d4_ce"
+
+/* These two options turn on line counting - useful for error messages - 
+   and debugging, respectively. When debugging is on, it's possible to see
+   which scanner rules are used at which points in the input. */
+%option yylineno
+%option debug
+
+/* Do not output the default rule (where any unmatched input is echoed to 
+   stdout). When set, nodefault will cause the scanner to exit on an error. */
+%option nodefault
+/* noyywrap makes the scanner assume that EOF/EOS is the end of the input.
+   If this is not set, the scanner will assume there are more files to 
+   scan. */ 
+%option noyywrap
+%option nounput
+/* When set, warn prints a message when the default rule can be matched
+   but nodefault is given (among other warnings). */
+%option warn
+
+%option batch
+
+%x quote
+
+/* This pattern just ensures that a word does not start with '#' which
+   is the DAP2 comment character. */
+WORD    [-+a-zA-Z0-9_%*\\~@!][-+a-zA-Z0-9_%*\\#~@!]* 
+
+%{
+// Code run each time a pattern is matched
+#define YY_USER_ACTION loc->columns(yyleng);
+%}
+
+%%
+
+%{
+// Code run each time yylex is called
+loc->step();
+%}
+
+"["     return token::LBRACKET;
+"]"     return token::RBRACKET;
+":"     return token::COLON;
+","		return token::COMMA;
+";"		return token::SEMICOLON;
+"|"     return token::PIPE;
+"{"		return token::LBRACE;
+"}"		return token::RBRACE;
+"/"     return token::GROUP_SEP;
+"."     return token::PATH_SEP;
+"="     return token::ASSIGN;
+
+"=="    return token::EQUAL;
+"!="    return token::NOT_EQUAL;
+">"	    return token::GREATER;
+">="    return token::GREATER_EQUAL;
+"<"     return token::LESS;
+"<="    return token::LESS_EQUAL;
+"~="    return token::REGEX_MATCH;
+"<<"    return token::LESS_BBOX;
+">>"    return token::GREATER_BBOX;
+"@="    return token::MASK;
+
+[ \t]+  /* ignore these */
+
+[\r\n]+ /* ignore these */
+
+{WORD}  { yylval->build<std::string>(yytext); return token::WORD; }
+
+<INITIAL><<EOF>> return token::END;
+
+["]    { BEGIN(quote); yymore(); }
+
+<quote>[^"\\]*  yymore(); /* Anything that's not a double quote or a backslash */
+
+<quote>[\\]["]	yymore(); /* This matches the escaped double quote (\") */
+
+<quote>[\\]{2}  yymore(); /* This matches an escaped escape (\\) */
+
+<quote>[\\]{1}  {
+                    BEGIN(INITIAL);
+                    if (yytext) {
+                        YY_FATAL_ERROR("Inside a string, backslash (\\) can escape a double quote or must itself be escaped (\\\\).");
+                    }
+                }
+
+<quote>["]  { 
+                /* An unescaped double quote in the 'quote' state indicates the end of the string */
+                BEGIN(INITIAL); 
+                yylval->build<std::string>(yytext); 
+                return token::STRING;
+            }
+
+<quote><<EOF>>	{
+                  BEGIN(INITIAL);   /* resetting the state is needed for reentrant parsers */
+                  YY_FATAL_ERROR("Unterminated quote");
+                }
+
+.   {
+        BEGIN(INITIAL);
+        if (yytext) {
+            YY_FATAL_ERROR("Characters found in the input were not recognized.");
+        }
+    }
+%%
diff --git a/d4_ce/d4_function_parser.tab.cc b/d4_ce/d4_function_parser.tab.cc
new file mode 100644
index 0000000..f84ab5a
--- /dev/null
+++ b/d4_ce/d4_function_parser.tab.cc
@@ -0,0 +1,2446 @@
+// A Bison parser, made by GNU Bison 3.0.1.
+
+// Skeleton implementation for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+
+// First part of user declarations.
+
+#line 37 "d4_function_parser.tab.cc" // lalr1.cc:399
+
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
+
+#include "d4_function_parser.tab.hh"
+
+// User implementation prologue.
+
+#line 51 "d4_function_parser.tab.cc" // lalr1.cc:407
+// Unqualified %code blocks.
+#line 77 "d4_function_parser.yy" // lalr1.cc:408
+
+    #include "BaseType.h"
+    #include "DMR.h"
+    #include "D4RValue.h"
+    #include "ServerFunctionsList.h"
+   
+    #include "parser-util.h"
+
+    /* include for all driver functions */
+    #include "D4FunctionEvaluator.h"
+
+    using namespace libdap ;
+    
+    /* this is silly, but I can't figure out a way around it */
+    static int yylex(libdap::D4FunctionParser::semantic_type *yylval,
+                     libdap::location *loc,
+                     libdap::D4FunctionScanner  &scanner,
+                     libdap::D4FunctionEvaluator   &evaluator);
+
+#line 73 "d4_function_parser.tab.cc" // lalr1.cc:408
+
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> // FIXME: INFRINGES ON USER NAME SPACE.
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
+/* 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).  */
+
+# ifndef YYLLOC_DEFAULT
+#  define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                  \
+      if (N)                                                            \
+        {                                                               \
+          (Current).begin  = YYRHSLOC (Rhs, 1).begin;                   \
+          (Current).end    = YYRHSLOC (Rhs, N).end;                     \
+        }                                                               \
+      else                                                              \
+        {                                                               \
+          (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end;      \
+        }                                                               \
+    while (/*CONSTCOND*/ false)
+# endif
+
+
+// Suppress unused-variable warnings by "using" E.
+#define YYUSE(E) ((void) (E))
+
+// Enable debugging if requested.
+#if YYDEBUG
+
+// A pseudo ostream that takes yydebug_ into account.
+# define YYCDEBUG if (yydebug_) (*yycdebug_)
+
+# define YY_SYMBOL_PRINT(Title, Symbol)         \
+  do {                                          \
+    if (yydebug_)                               \
+    {                                           \
+      *yycdebug_ << Title << ' ';               \
+      yy_print_ (*yycdebug_, Symbol);           \
+      *yycdebug_ << std::endl;                  \
+    }                                           \
+  } while (false)
+
+# define YY_REDUCE_PRINT(Rule)          \
+  do {                                  \
+    if (yydebug_)                       \
+      yy_reduce_print_ (Rule);          \
+  } while (false)
+
+# define YY_STACK_PRINT()               \
+  do {                                  \
+    if (yydebug_)                       \
+      yystack_print_ ();                \
+  } while (false)
+
+#else // !YYDEBUG
+
+# define YYCDEBUG if (false) std::cerr
+# define YY_SYMBOL_PRINT(Title, Symbol)  YYUSE(Symbol)
+# define YY_REDUCE_PRINT(Rule)           static_cast<void>(0)
+# define YY_STACK_PRINT()                static_cast<void>(0)
+
+#endif // !YYDEBUG
+
+#define yyerrok         (yyerrstatus_ = 0)
+#define yyclearin       (yyempty = true)
+
+#define YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
+#define YYRECOVERING()  (!!yyerrstatus_)
+
+#line 34 "d4_function_parser.yy" // lalr1.cc:474
+namespace libdap {
+#line 159 "d4_function_parser.tab.cc" // lalr1.cc:474
+
+  /* Return 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.  */
+  std::string
+  D4FunctionParser::yytnamerr_ (const char *yystr)
+  {
+    if (*yystr == '"')
+      {
+        std::string yyr = "";
+        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:
+              yyr += *yyp;
+              break;
+
+            case '"':
+              return yyr;
+            }
+      do_not_strip_quotes: ;
+      }
+
+    return yystr;
+  }
+
+
+  /// Build a parser object.
+  D4FunctionParser::D4FunctionParser (D4FunctionScanner  &scanner_yyarg, D4FunctionEvaluator  &evaluator_yyarg)
+    :
+#if YYDEBUG
+      yydebug_ (false),
+      yycdebug_ (&std::cerr),
+#endif
+      scanner (scanner_yyarg),
+      evaluator (evaluator_yyarg)
+  {}
+
+  D4FunctionParser::~D4FunctionParser ()
+  {}
+
+
+  /*---------------.
+  | Symbol types.  |
+  `---------------*/
+
+  inline
+  D4FunctionParser::syntax_error::syntax_error (const location_type& l, const std::string& m)
+    : std::runtime_error (m)
+    , location (l)
+  {}
+
+  // basic_symbol.
+  template <typename Base>
+  inline
+  D4FunctionParser::basic_symbol<Base>::basic_symbol ()
+    : value ()
+  {}
+
+  template <typename Base>
+  inline
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
+    : Base (other)
+    , value ()
+    , location (other.location)
+  {
+      switch (other.type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.copy< D4Function > (other.value);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.copy< D4RValue* > (other.value);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.copy< D4RValueList* > (other.value);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.copy< std::string > (other.value);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.copy< std::vector<dods_byte>* > (other.value);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.copy< std::vector<dods_float32>* > (other.value);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.copy< std::vector<dods_float64>* > (other.value);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.copy< std::vector<dods_int16>* > (other.value);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.copy< std::vector<dods_int32>* > (other.value);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.copy< std::vector<dods_int64>* > (other.value);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.copy< std::vector<dods_int8>* > (other.value);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.copy< std::vector<dods_uint16>* > (other.value);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.copy< std::vector<dods_uint32>* > (other.value);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.copy< std::vector<dods_uint64>* > (other.value);
+        break;
+
+      default:
+        break;
+    }
+
+  }
+
+
+  template <typename Base>
+  inline
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const semantic_type& v, const location_type& l)
+    : Base (t)
+    , value ()
+    , location (l)
+  {
+    (void) v;
+      switch (this->type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.copy< D4Function > (v);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.copy< D4RValue* > (v);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.copy< D4RValueList* > (v);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.copy< std::string > (v);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.copy< std::vector<dods_byte>* > (v);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.copy< std::vector<dods_float32>* > (v);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.copy< std::vector<dods_float64>* > (v);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.copy< std::vector<dods_int16>* > (v);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.copy< std::vector<dods_int32>* > (v);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.copy< std::vector<dods_int64>* > (v);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.copy< std::vector<dods_int8>* > (v);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.copy< std::vector<dods_uint16>* > (v);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.copy< std::vector<dods_uint32>* > (v);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.copy< std::vector<dods_uint64>* > (v);
+        break;
+
+      default:
+        break;
+    }
+}
+
+
+  // Implementation of basic_symbol constructor for each type.
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const location_type& l)
+    : Base (t)
+    , value ()
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const D4Function v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const D4RValue* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const D4RValueList* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_byte>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_float32>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_float64>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_int16>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_int32>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_int64>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_int8>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_uint16>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_uint32>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_uint64>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+
+  template <typename Base>
+  inline
+  D4FunctionParser::basic_symbol<Base>::~basic_symbol ()
+  {
+    // User destructor.
+    symbol_number_type yytype = this->type_get ();
+    switch (yytype)
+    {
+   default:
+      break;
+    }
+
+    // Type destructor.
+    switch (yytype)
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.template destroy< D4Function > ();
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.template destroy< D4RValue* > ();
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.template destroy< D4RValueList* > ();
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.template destroy< std::string > ();
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.template destroy< std::vector<dods_byte>* > ();
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.template destroy< std::vector<dods_float32>* > ();
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.template destroy< std::vector<dods_float64>* > ();
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.template destroy< std::vector<dods_int16>* > ();
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.template destroy< std::vector<dods_int32>* > ();
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.template destroy< std::vector<dods_int64>* > ();
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.template destroy< std::vector<dods_int8>* > ();
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.template destroy< std::vector<dods_uint16>* > ();
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.template destroy< std::vector<dods_uint32>* > ();
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.template destroy< std::vector<dods_uint64>* > ();
+        break;
+
+      default:
+        break;
+    }
+
+  }
+
+  template <typename Base>
+  inline
+  void
+  D4FunctionParser::basic_symbol<Base>::move (basic_symbol& s)
+  {
+    super_type::move(s);
+      switch (this->type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.move< D4Function > (s.value);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.move< D4RValue* > (s.value);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.move< D4RValueList* > (s.value);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.move< std::string > (s.value);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.move< std::vector<dods_byte>* > (s.value);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.move< std::vector<dods_float32>* > (s.value);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.move< std::vector<dods_float64>* > (s.value);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.move< std::vector<dods_int16>* > (s.value);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.move< std::vector<dods_int32>* > (s.value);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.move< std::vector<dods_int64>* > (s.value);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.move< std::vector<dods_int8>* > (s.value);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.move< std::vector<dods_uint16>* > (s.value);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.move< std::vector<dods_uint32>* > (s.value);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.move< std::vector<dods_uint64>* > (s.value);
+        break;
+
+      default:
+        break;
+    }
+
+    location = s.location;
+  }
+
+  // by_type.
+  inline
+  D4FunctionParser::by_type::by_type ()
+     : type (empty)
+  {}
+
+  inline
+  D4FunctionParser::by_type::by_type (const by_type& other)
+    : type (other.type)
+  {}
+
+  inline
+  D4FunctionParser::by_type::by_type (token_type t)
+    : type (yytranslate_ (t))
+  {}
+
+  inline
+  void
+  D4FunctionParser::by_type::move (by_type& that)
+  {
+    type = that.type;
+    that.type = empty;
+  }
+
+  inline
+  int
+  D4FunctionParser::by_type::type_get () const
+  {
+    return type;
+  }
+  // Implementation of make_symbol for each symbol type.
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_END (const location_type& l)
+  {
+    return symbol_type (token::END, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_WORD (const std::string& v, const location_type& l)
+  {
+    return symbol_type (token::WORD, v, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_STRING (const std::string& v, const location_type& l)
+  {
+    return symbol_type (token::STRING, v, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_SEMICOLON (const location_type& l)
+  {
+    return symbol_type (token::SEMICOLON, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_COLON (const location_type& l)
+  {
+    return symbol_type (token::COLON, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_LPAREN (const location_type& l)
+  {
+    return symbol_type (token::LPAREN, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_RPAREN (const location_type& l)
+  {
+    return symbol_type (token::RPAREN, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_COMMA (const location_type& l)
+  {
+    return symbol_type (token::COMMA, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_GROUP_SEP (const location_type& l)
+  {
+    return symbol_type (token::GROUP_SEP, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_PATH_SEP (const location_type& l)
+  {
+    return symbol_type (token::PATH_SEP, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_BYTE (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_BYTE, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_UINT8 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_UINT8, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_INT8 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_INT8, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_UINT16 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_UINT16, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_INT16 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_INT16, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_UINT32 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_UINT32, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_INT32 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_INT32, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_UINT64 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_UINT64, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_INT64 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_INT64, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_FLOAT32 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_FLOAT32, l);
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_FLOAT64 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_FLOAT64, l);
+  }
+
+
+
+  // by_state.
+  inline
+  D4FunctionParser::by_state::by_state ()
+    : state (empty)
+  {}
+
+  inline
+  D4FunctionParser::by_state::by_state (const by_state& other)
+    : state (other.state)
+  {}
+
+  inline
+  void
+  D4FunctionParser::by_state::move (by_state& that)
+  {
+    state = that.state;
+    that.state = empty;
+  }
+
+  inline
+  D4FunctionParser::by_state::by_state (state_type s)
+    : state (s)
+  {}
+
+  inline
+  D4FunctionParser::symbol_number_type
+  D4FunctionParser::by_state::type_get () const
+  {
+    return state == empty ? 0 : yystos_[state];
+  }
+
+  inline
+  D4FunctionParser::stack_symbol_type::stack_symbol_type ()
+  {}
+
+
+  inline
+  D4FunctionParser::stack_symbol_type::stack_symbol_type (state_type s, symbol_type& that)
+    : super_type (s, that.location)
+  {
+      switch (that.type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.move< D4Function > (that.value);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.move< D4RValue* > (that.value);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.move< D4RValueList* > (that.value);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.move< std::string > (that.value);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.move< std::vector<dods_byte>* > (that.value);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.move< std::vector<dods_float32>* > (that.value);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.move< std::vector<dods_float64>* > (that.value);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.move< std::vector<dods_int16>* > (that.value);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.move< std::vector<dods_int32>* > (that.value);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.move< std::vector<dods_int64>* > (that.value);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.move< std::vector<dods_int8>* > (that.value);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.move< std::vector<dods_uint16>* > (that.value);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.move< std::vector<dods_uint32>* > (that.value);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.move< std::vector<dods_uint64>* > (that.value);
+        break;
+
+      default:
+        break;
+    }
+
+    // that is emptied.
+    that.type = empty;
+  }
+
+  inline
+  D4FunctionParser::stack_symbol_type&
+  D4FunctionParser::stack_symbol_type::operator= (const stack_symbol_type& that)
+  {
+    state = that.state;
+      switch (that.type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.copy< D4Function > (that.value);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.copy< D4RValue* > (that.value);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.copy< D4RValueList* > (that.value);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.copy< std::string > (that.value);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.copy< std::vector<dods_byte>* > (that.value);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.copy< std::vector<dods_float32>* > (that.value);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.copy< std::vector<dods_float64>* > (that.value);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.copy< std::vector<dods_int16>* > (that.value);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.copy< std::vector<dods_int32>* > (that.value);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.copy< std::vector<dods_int64>* > (that.value);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.copy< std::vector<dods_int8>* > (that.value);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.copy< std::vector<dods_uint16>* > (that.value);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.copy< std::vector<dods_uint32>* > (that.value);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.copy< std::vector<dods_uint64>* > (that.value);
+        break;
+
+      default:
+        break;
+    }
+
+    location = that.location;
+    return *this;
+  }
+
+
+  template <typename Base>
+  inline
+  void
+  D4FunctionParser::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
+  {
+    if (yymsg)
+      YY_SYMBOL_PRINT (yymsg, yysym);
+  }
+
+#if YYDEBUG
+  template <typename Base>
+  void
+  D4FunctionParser::yy_print_ (std::ostream& yyo,
+                                     const basic_symbol<Base>& yysym) const
+  {
+    std::ostream& yyoutput = yyo;
+    YYUSE (yyoutput);
+    symbol_number_type yytype = yysym.type_get ();
+    yyo << (yytype < yyntokens_ ? "token" : "nterm")
+        << ' ' << yytname_[yytype] << " ("
+        << yysym.location << ": ";
+    YYUSE (yytype);
+    yyo << ')';
+  }
+#endif
+
+  inline
+  void
+  D4FunctionParser::yypush_ (const char* m, state_type s, symbol_type& sym)
+  {
+    stack_symbol_type t (s, sym);
+    yypush_ (m, t);
+  }
+
+  inline
+  void
+  D4FunctionParser::yypush_ (const char* m, stack_symbol_type& s)
+  {
+    if (m)
+      YY_SYMBOL_PRINT (m, s);
+    yystack_.push (s);
+  }
+
+  inline
+  void
+  D4FunctionParser::yypop_ (unsigned int n)
+  {
+    yystack_.pop (n);
+  }
+
+#if YYDEBUG
+  std::ostream&
+  D4FunctionParser::debug_stream () const
+  {
+    return *yycdebug_;
+  }
+
+  void
+  D4FunctionParser::set_debug_stream (std::ostream& o)
+  {
+    yycdebug_ = &o;
+  }
+
+
+  D4FunctionParser::debug_level_type
+  D4FunctionParser::debug_level () const
+  {
+    return yydebug_;
+  }
+
+  void
+  D4FunctionParser::set_debug_level (debug_level_type l)
+  {
+    yydebug_ = l;
+  }
+#endif // YYDEBUG
+
+  inline D4FunctionParser::state_type
+  D4FunctionParser::yy_lr_goto_state_ (state_type yystate, int yylhs)
+  {
+    int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
+    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+      return yytable_[yyr];
+    else
+      return yydefgoto_[yylhs - yyntokens_];
+  }
+
+  inline bool
+  D4FunctionParser::yy_pact_value_is_default_ (int yyvalue)
+  {
+    return yyvalue == yypact_ninf_;
+  }
+
+  inline bool
+  D4FunctionParser::yy_table_value_is_error_ (int yyvalue)
+  {
+    return yyvalue == yytable_ninf_;
+  }
+
+  int
+  D4FunctionParser::parse ()
+  {
+    /// Whether yyla contains a lookahead.
+    bool yyempty = true;
+
+    // State.
+    int yyn;
+    int yylen = 0;
+
+    // Error handling.
+    int yynerrs_ = 0;
+    int yyerrstatus_ = 0;
+
+    /// The lookahead symbol.
+    symbol_type yyla;
+
+    /// The locations where the error started and ended.
+    stack_symbol_type yyerror_range[3];
+
+    /// $$ and @$.
+    stack_symbol_type yylhs;
+
+    /// The return value of parse ().
+    int yyresult;
+
+    // FIXME: This shoud be completely indented.  It is not yet to
+    // avoid gratuitous conflicts when merging into the master branch.
+    try
+      {
+    YYCDEBUG << "Starting parse" << std::endl;
+
+
+    // User initialization code.
+    #line 69 "d4_function_parser.yy" // lalr1.cc:727
+{
+    // Initialize the initial location. This is printed when the parser builds
+    // its own error messages - when the parse fails as opposed to when the 
+    // function(s) name(s) a missing variable, ...
+
+    yyla.location.initialize (evaluator.expression());
+}
+
+#line 1266 "d4_function_parser.tab.cc" // lalr1.cc:727
+
+    /* Initialize the stack.  The initial state will be set in
+       yynewstate, since the latter expects the semantical and the
+       location values to have been already stored, initialize these
+       stacks with a primary value.  */
+    yystack_.clear ();
+    yypush_ (YY_NULLPTR, 0, yyla);
+
+    // A new symbol was pushed on the stack.
+  yynewstate:
+    YYCDEBUG << "Entering state " << yystack_[0].state << std::endl;
+
+    // Accept?
+    if (yystack_[0].state == yyfinal_)
+      goto yyacceptlab;
+
+    goto yybackup;
+
+    // Backup.
+  yybackup:
+
+    // Try to take a decision without lookahead.
+    yyn = yypact_[yystack_[0].state];
+    if (yy_pact_value_is_default_ (yyn))
+      goto yydefault;
+
+    // Read a lookahead token.
+    if (yyempty)
+      {
+        YYCDEBUG << "Reading a token: ";
+        try
+          {
+            yyla.type = yytranslate_ (yylex (&yyla.value, &yyla.location, scanner, evaluator));
+          }
+        catch (const syntax_error& yyexc)
+          {
+            error (yyexc);
+            goto yyerrlab1;
+          }
+        yyempty = false;
+      }
+    YY_SYMBOL_PRINT ("Next token is", yyla);
+
+    /* If the proper action on seeing token YYLA.TYPE is to reduce or
+       to detect an error, take that action.  */
+    yyn += yyla.type_get ();
+    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
+      goto yydefault;
+
+    // Reduce or error.
+    yyn = yytable_[yyn];
+    if (yyn <= 0)
+      {
+        if (yy_table_value_is_error_ (yyn))
+          goto yyerrlab;
+        yyn = -yyn;
+        goto yyreduce;
+      }
+
+    // Discard the token being shifted.
+    yyempty = true;
+
+    // Count tokens shifted since error; after three, turn off error status.
+    if (yyerrstatus_)
+      --yyerrstatus_;
+
+    // Shift the lookahead token.
+    yypush_ ("Shifting", yyn, yyla);
+    goto yynewstate;
+
+  /*-----------------------------------------------------------.
+  | yydefault -- do the default action for the current state.  |
+  `-----------------------------------------------------------*/
+  yydefault:
+    yyn = yydefact_[yystack_[0].state];
+    if (yyn == 0)
+      goto yyerrlab;
+    goto yyreduce;
+
+  /*-----------------------------.
+  | yyreduce -- Do a reduction.  |
+  `-----------------------------*/
+  yyreduce:
+    yylen = yyr2_[yyn];
+    yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);
+    /* Variants are always initialized to an empty instance of the
+       correct type. The default $$=$1 action is NOT applied when using
+       variants.  */
+      switch (yyr1_[yyn])
+    {
+      case 7: // "function name"
+      case 44: // fname
+        yylhs.value.build< D4Function > ();
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        yylhs.value.build< D4RValue* > ();
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        yylhs.value.build< D4RValueList* > ();
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        yylhs.value.build< std::string > ();
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        yylhs.value.build< std::vector<dods_byte>* > ();
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        yylhs.value.build< std::vector<dods_float32>* > ();
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        yylhs.value.build< std::vector<dods_float64>* > ();
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        yylhs.value.build< std::vector<dods_int16>* > ();
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        yylhs.value.build< std::vector<dods_int32>* > ();
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        yylhs.value.build< std::vector<dods_int64>* > ();
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        yylhs.value.build< std::vector<dods_int8>* > ();
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        yylhs.value.build< std::vector<dods_uint16>* > ();
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        yylhs.value.build< std::vector<dods_uint32>* > ();
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        yylhs.value.build< std::vector<dods_uint64>* > ();
+        break;
+
+      default:
+        break;
+    }
+
+
+    // Compute the default @$.
+    {
+      slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
+      YYLLOC_DEFAULT (yylhs.location, slice, yylen);
+    }
+
+    // Perform the reduction.
+    YY_REDUCE_PRINT (yyn);
+    try
+      {
+        switch (yyn)
+          {
+  case 2:
+#line 156 "d4_function_parser.yy" // lalr1.cc:847
+    { 
+    evaluator.set_result(yystack_[0].value.as< D4RValueList* > ()); 
+}
+#line 1461 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 3:
+#line 162 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValueList* > () = new D4RValueList(yystack_[0].value.as< D4RValue* > ()); 
+}
+#line 1469 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 4:
+#line 166 "d4_function_parser.yy" // lalr1.cc:847
+    { 
+    yystack_[2].value.as< D4RValueList* > ()->add_rvalue(yystack_[0].value.as< D4RValue* > ());
+    yylhs.value.as< D4RValueList* > () = yystack_[2].value.as< D4RValueList* > (); 
+}
+#line 1478 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 5:
+#line 173 "d4_function_parser.yy" // lalr1.cc:847
+    { 
+    yylhs.value.as< D4RValue* > () = new D4RValue(yystack_[3].value.as< D4Function > (), yystack_[1].value.as< D4RValueList* > ()); // Build a D4RValue from a D4Function pointer and a D4RValueList 
+}
+#line 1486 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 6:
+#line 179 "d4_function_parser.yy" // lalr1.cc:847
+    { 
+    D4Function f;
+    if (!evaluator.sf_list()->find_function(yystack_[0].value.as< std::string > (), &f)) {
+        // ...cloud use @1.{first,last}_column in these error messages.
+        throw Error("'" + yystack_[0].value.as< std::string > () + "' is not a registered DAP4 server function.");
+    }
+
+    yylhs.value.as< D4Function > () = f;
+}
+#line 1500 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 7:
+#line 191 "d4_function_parser.yy" // lalr1.cc:847
+    { 
+    yylhs.value.as< D4RValueList* > () = new D4RValueList(yystack_[0].value.as< D4RValue* > ()); // build a D4RValueList from the D4RValue
+}
+#line 1508 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 8:
+#line 195 "d4_function_parser.yy" // lalr1.cc:847
+    { 
+    yystack_[2].value.as< D4RValueList* > ()->add_rvalue(yystack_[0].value.as< D4RValue* > ());
+    yylhs.value.as< D4RValueList* > () = yystack_[2].value.as< D4RValueList* > (); // Append the D4RValue ($3) to the D4RValueList ($1), then return
+}
+#line 1517 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 9:
+#line 202 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = yystack_[0].value.as< D4RValue* > ();
+}
+#line 1525 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 10:
+#line 206 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = yystack_[0].value.as< D4RValue* > ();
+}
+#line 1533 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 11:
+#line 210 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = yystack_[0].value.as< D4RValue* > ();
+}
+#line 1541 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 12:
+#line 216 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    D4RValue *rvalue = evaluator.build_rvalue(yystack_[0].value.as< std::string > ());
+    if (!rvalue) {
+        throw Error("'" + yystack_[0].value.as< std::string > () + "' is not a variable, number or string.");
+    }
+    
+    yylhs.value.as< D4RValue* > () = rvalue;
+}
+#line 1554 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 13:
+#line 228 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_byte>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_byte>* > ();
+}
+#line 1563 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 14:
+#line 234 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_byte>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_byte>* > ();
+}
+#line 1572 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 15:
+#line 240 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_int8>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_int8>* > ();
+}
+#line 1581 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 16:
+#line 246 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_uint16>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_uint16>* > ();
+}
+#line 1590 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 17:
+#line 252 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_int16>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_int16>* > ();
+}
+#line 1599 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 18:
+#line 258 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_uint32>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_uint32>* > ();
+}
+#line 1608 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 19:
+#line 264 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_int32>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_int32>* > ();
+}
+#line 1617 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 20:
+#line 270 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_uint64>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_uint64>* > ();
+}
+#line 1626 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 21:
+#line 276 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_int64>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_int64>* > ();
+}
+#line 1635 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 22:
+#line 282 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_float32>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_float32>* > ();
+}
+#line 1644 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 23:
+#line 288 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_float64>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_float64>* > ();
+}
+#line 1653 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 24:
+#line 300 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    evaluator.set_arg_length_hint(get_ull(yystack_[0].value.as< std::string > ().c_str()));
+}
+#line 1661 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 25:
+#line 306 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_byte>* > () = evaluator.init_arg_list(dods_byte(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1669 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 26:
+#line 310 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_byte>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_byte>* > () = yystack_[2].value.as< std::vector<dods_byte>* > ();
+}
+#line 1678 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 27:
+#line 317 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_int8>* > () = evaluator.init_arg_list(dods_int8(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1686 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 28:
+#line 321 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_int8>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_int8>* > () = yystack_[2].value.as< std::vector<dods_int8>* > ();
+}
+#line 1695 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 29:
+#line 328 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_uint16>* > () = evaluator.init_arg_list(dods_uint16(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1703 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 30:
+#line 332 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_uint16>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_uint16>* > () = yystack_[2].value.as< std::vector<dods_uint16>* > ();
+}
+#line 1712 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 31:
+#line 339 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_int16>* > () = evaluator.init_arg_list(dods_int16(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1720 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 32:
+#line 343 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_int16>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_int16>* > () = yystack_[2].value.as< std::vector<dods_int16>* > ();
+}
+#line 1729 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 33:
+#line 350 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_uint32>* > () = evaluator.init_arg_list(dods_uint32(strtoul(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1737 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 34:
+#line 354 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_uint32>* > ()->push_back(strtoul(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_uint32>* > () = yystack_[2].value.as< std::vector<dods_uint32>* > ();
+}
+#line 1746 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 35:
+#line 360 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_int32>* > () = evaluator.init_arg_list(dods_int32(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1754 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 36:
+#line 364 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_int32>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_int32>* > () = yystack_[2].value.as< std::vector<dods_int32>* > ();
+}
+#line 1763 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 37:
+#line 371 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_uint64>* > () = evaluator.init_arg_list(dods_uint64(strtoull(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1771 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 38:
+#line 375 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_uint64>* > ()->push_back(strtoull(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_uint64>* > () = yystack_[2].value.as< std::vector<dods_uint64>* > ();
+}
+#line 1780 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 39:
+#line 382 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_int64>* > () = evaluator.init_arg_list(dods_int64(strtoll(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1788 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 40:
+#line 386 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_int64>* > ()->push_back(strtoll(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_int64>* > () = yystack_[2].value.as< std::vector<dods_int64>* > ();
+}
+#line 1797 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 41:
+#line 396 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_float32>* > () = evaluator.init_arg_list(dods_float32(strtof(yystack_[0].value.as< std::string > ().c_str(), 0)));
+}
+#line 1805 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 42:
+#line 400 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_float32>* > ()->push_back(strtof(yystack_[0].value.as< std::string > ().c_str(), 0));
+    yylhs.value.as< std::vector<dods_float32>* > () = yystack_[2].value.as< std::vector<dods_float32>* > ();
+}
+#line 1814 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 43:
+#line 407 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::vector<dods_float64>* > () = evaluator.init_arg_list(dods_float64(strtod(yystack_[0].value.as< std::string > ().c_str(), 0)));
+}
+#line 1822 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 44:
+#line 411 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::vector<dods_float64>* > ()->push_back(strtod(yystack_[0].value.as< std::string > ().c_str(), 0));
+    yylhs.value.as< std::vector<dods_float64>* > () = yystack_[2].value.as< std::vector<dods_float64>* > ();
+}
+#line 1831 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 45:
+#line 418 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > () = yystack_[0].value.as< std::string > ();
+}
+#line 1839 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 46:
+#line 422 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > ().append("/");
+    yylhs.value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+}
+#line 1848 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 47:
+#line 427 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::string > ().append("/");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1858 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 48:
+#line 435 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > ().append("/");
+    yylhs.value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+}
+#line 1867 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 49:
+#line 440 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::string > ().append(".");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1877 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 50:
+#line 448 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > () = yystack_[0].value.as< std::string > ();
+}
+#line 1885 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 51:
+#line 452 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yystack_[2].value.as< std::string > ().append(".");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1895 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 52:
+#line 463 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > ()=yystack_[0].value.as< std::string > ();
+}
+#line 1903 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+  case 53:
+#line 467 "d4_function_parser.yy" // lalr1.cc:847
+    {
+    yylhs.value.as< std::string > ()=yystack_[0].value.as< std::string > ();
+}
+#line 1911 "d4_function_parser.tab.cc" // lalr1.cc:847
+    break;
+
+
+#line 1915 "d4_function_parser.tab.cc" // lalr1.cc:847
+          default:
+            break;
+          }
+      }
+    catch (const syntax_error& yyexc)
+      {
+        error (yyexc);
+        YYERROR;
+      }
+    YY_SYMBOL_PRINT ("-> $$ =", yylhs);
+    yypop_ (yylen);
+    yylen = 0;
+    YY_STACK_PRINT ();
+
+    // Shift the result of the reduction.
+    yypush_ (YY_NULLPTR, yylhs);
+    goto yynewstate;
+
+  /*--------------------------------------.
+  | yyerrlab -- here on detecting error.  |
+  `--------------------------------------*/
+  yyerrlab:
+    // If not already recovering from an error, report this error.
+    if (!yyerrstatus_)
+      {
+        ++yynerrs_;
+        error (yyla.location, yysyntax_error_ (yystack_[0].state,
+                                           yyempty ? yyempty_ : yyla.type_get ()));
+      }
+
+
+    yyerror_range[1].location = yyla.location;
+    if (yyerrstatus_ == 3)
+      {
+        /* If just tried and failed to reuse lookahead token after an
+           error, discard it.  */
+
+        // Return failure if at end of input.
+        if (yyla.type_get () == yyeof_)
+          YYABORT;
+        else if (!yyempty)
+          {
+            yy_destroy_ ("Error: discarding", yyla);
+            yyempty = true;
+          }
+      }
+
+    // Else will try to reuse lookahead 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 (false)
+      goto yyerrorlab;
+    yyerror_range[1].location = yystack_[yylen - 1].location;
+    /* $$ was initialized before running the user action.  */
+    YY_SYMBOL_PRINT ("Error: discarding", yylhs);
+    yylhs.~stack_symbol_type();
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYERROR.  */
+    yypop_ (yylen);
+    yylen = 0;
+    goto yyerrlab1;
+
+  /*-------------------------------------------------------------.
+  | yyerrlab1 -- common code for both syntax error and YYERROR.  |
+  `-------------------------------------------------------------*/
+  yyerrlab1:
+    yyerrstatus_ = 3;   // Each real token shifted decrements this.
+    {
+      stack_symbol_type error_token;
+      for (;;)
+        {
+          yyn = yypact_[yystack_[0].state];
+          if (!yy_pact_value_is_default_ (yyn))
+            {
+              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 (yystack_.size () == 1)
+            YYABORT;
+
+          yyerror_range[1].location = yystack_[0].location;
+          yy_destroy_ ("Error: popping", yystack_[0]);
+          yypop_ ();
+          YY_STACK_PRINT ();
+        }
+
+      yyerror_range[2].location = yyla.location;
+      YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);
+
+      // Shift the error token.
+      error_token.state = yyn;
+      yypush_ ("Shifting", error_token);
+    }
+    goto yynewstate;
+
+    // Accept.
+  yyacceptlab:
+    yyresult = 0;
+    goto yyreturn;
+
+    // Abort.
+  yyabortlab:
+    yyresult = 1;
+    goto yyreturn;
+
+  yyreturn:
+    if (!yyempty)
+      yy_destroy_ ("Cleanup: discarding lookahead", yyla);
+
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYABORT or YYACCEPT.  */
+    yypop_ (yylen);
+    while (1 < yystack_.size ())
+      {
+        yy_destroy_ ("Cleanup: popping", yystack_[0]);
+        yypop_ ();
+      }
+
+    return yyresult;
+  }
+    catch (...)
+      {
+        YYCDEBUG << "Exception caught: cleaning lookahead and stack"
+                 << std::endl;
+        // Do not try to display the values of the reclaimed symbols,
+        // as their printer might throw an exception.
+        if (!yyempty)
+          yy_destroy_ (YY_NULLPTR, yyla);
+
+        while (1 < yystack_.size ())
+          {
+            yy_destroy_ (YY_NULLPTR, yystack_[0]);
+            yypop_ ();
+          }
+        throw;
+      }
+  }
+
+  void
+  D4FunctionParser::error (const syntax_error& yyexc)
+  {
+    error (yyexc.location, yyexc.what());
+  }
+
+  // Generate an error message.
+  std::string
+  D4FunctionParser::yysyntax_error_ (state_type yystate, symbol_number_type yytoken) const
+  {
+    std::string yyres;
+    // Number of reported tokens (one for the "unexpected", one per
+    // "expected").
+    size_t yycount = 0;
+    // Its maximum.
+    enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+    // Arguments of yyformat.
+    char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+
+    /* There are many possibilities here to consider:
+       - If this state is a consistent state with a default action, then
+         the only way this function was invoked is if the default action
+         is an error action.  In that case, don't check for expected
+         tokens because there are none.
+       - The only way there can be no lookahead present (in yytoken) is
+         if this state is a consistent state with a default action.
+         Thus, detecting the absence of a lookahead is sufficient to
+         determine that there is no unexpected or expected token to
+         report.  In that case, just report a simple "syntax error".
+       - Don't assume there isn't a lookahead just because this state is
+         a consistent state with a default action.  There might have
+         been a previous inconsistent state, consistent state with a
+         non-default action, or user semantic action that manipulated
+         yyla.  (However, yyla is currently not documented for users.)
+       - Of course, the expected token list depends on states to have
+         correct lookahead information, and it depends on the parser not
+         to perform extra reductions after fetching a lookahead from the
+         scanner and before detecting a syntax error.  Thus, state
+         merging (from LALR or IELR) and default reductions corrupt the
+         expected token list.  However, the list is correct for
+         canonical LR with one exception: it will still contain any
+         token that will not be accepted due to an error action in a
+         later state.
+    */
+    if (yytoken != yyempty_)
+      {
+        yyarg[yycount++] = yytname_[yytoken];
+        int yyn = yypact_[yystate];
+        if (!yy_pact_value_is_default_ (yyn))
+          {
+            /* Start YYX at -YYN if negative to avoid negative indexes in
+               YYCHECK.  In other words, skip the first -YYN actions for
+               this state because they are default actions.  */
+            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_;
+            for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+              if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
+                  && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
+                {
+                  if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                    {
+                      yycount = 1;
+                      break;
+                    }
+                  else
+                    yyarg[yycount++] = yytname_[yyx];
+                }
+          }
+      }
+
+    char const* yyformat = YY_NULLPTR;
+    switch (yycount)
+      {
+#define YYCASE_(N, S)                         \
+        case N:                               \
+          yyformat = S;                       \
+        break
+        YYCASE_(0, YY_("syntax error"));
+        YYCASE_(1, YY_("syntax error, unexpected %s"));
+        YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+        YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+        YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+        YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+#undef YYCASE_
+      }
+
+    // Argument number.
+    size_t yyi = 0;
+    for (char const* yyp = yyformat; *yyp; ++yyp)
+      if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
+        {
+          yyres += yytnamerr_ (yyarg[yyi++]);
+          ++yyp;
+        }
+      else
+        yyres += *yyp;
+    return yyres;
+  }
+
+
+  const signed char D4FunctionParser::yypact_ninf_ = -20;
+
+  const signed char D4FunctionParser::yytable_ninf_ = -50;
+
+  const signed char
+  D4FunctionParser::yypact_[] =
+  {
+     -10,   -20,     8,    10,   -20,    12,   -20,   -10,   -18,   -20,
+      37,   -20,   -16,    38,    39,    42,    43,    44,    45,    46,
+      47,    48,    49,    50,   -20,   -19,   -20,   -20,   -20,   -20,
+      51,    52,   -20,   -20,    52,    54,    55,    55,    55,    55,
+      55,    55,    55,    55,    55,    55,    55,   -20,   -18,   -16,
+     -16,   -20,    53,    56,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,   -20,    52,    68,   -20,    57,    57,    71,
+      72,    73,    74,    76,    77,    78,   -16,   -16,   -20,     9,
+      16,   -20,    18,   -20,    20,   -20,    22,   -20,    24,   -20,
+      26,   -20,    28,   -20,    30,    32,    52,    34,    52,   -20,
+      79,   -20,   -20,    80,   -20,    81,   -20,    82,   -20,    83,
+     -20,    84,   -20,    86,   -20,    88,   -20,   -16,   -20,   -16,
+     -20,   -20,   -20,   -20,   -20,   -20,   -20,   -20,    52,    52
+  };
+
+  const unsigned char
+  D4FunctionParser::yydefact_[] =
+  {
+       0,     6,     0,     2,     3,     0,     1,     0,     0,     4,
+      52,    53,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     9,     0,     7,    10,    11,    12,
+       0,    45,    50,    52,    46,    50,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     5,     0,     0,
+       0,    24,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     8,    47,    50,    51,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    25,     0,
+       0,    27,     0,    29,     0,    31,     0,    33,     0,    35,
+       0,    37,     0,    39,     0,     0,    41,     0,    43,    13,
+       0,    14,    15,     0,    16,     0,    17,     0,    18,     0,
+      19,     0,    20,     0,    21,     0,    22,     0,    23,     0,
+      26,    28,    30,    32,    34,    36,    38,    40,    42,    44
+  };
+
+  const signed char
+  D4FunctionParser::yypgoto_[] =
+  {
+     -20,   -20,   -20,    33,   -20,   -20,    69,   -20,   -20,   -15,
+      41,   -20,   -20,   -20,   -20,   -20,   -20,   -20,   -20,   -20,
+     -20,   -20,   -12,   -11
+  };
+
+  const signed char
+  D4FunctionParser::yydefgoto_[] =
+  {
+      -1,     2,     3,    24,     5,    25,    26,    27,    28,    52,
+      79,    82,    84,    86,    88,    90,    92,    94,    95,    97,
+      29,    30,    31,    32
+  };
+
+  const short int
+  D4FunctionParser::yytable_[] =
+  {
+      34,    35,    10,    11,    33,    11,    47,    48,     6,    12,
+       1,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    23,    53,    54,    55,    56,    57,    58,    59,    60,
+      61,    62,     7,     4,    99,   100,     8,    64,    65,    66,
+       9,   101,   100,   102,   103,   104,   105,   106,   107,   108,
+     109,   110,   111,   112,   113,   114,   115,   116,   117,   118,
+     119,    -6,    36,    37,    96,    98,    38,    39,    40,    41,
+      42,    43,    44,    45,    46,    51,    67,    78,    49,    68,
+      50,   -48,    69,    70,    71,    72,    73,    74,    75,    76,
+      77,    81,    83,    85,    87,   -49,    89,    91,    93,   120,
+     121,   122,   123,   124,   125,   128,   126,   129,   127,    80,
+       0,     0,     0,     0,     0,     0,     0,    63
+  };
+
+  const signed char
+  D4FunctionParser::yycheck_[] =
+  {
+      12,    12,    20,    21,    20,    21,    25,    26,     0,    27,
+      20,    29,    30,    31,    32,    33,    34,    35,    36,    37,
+      38,    39,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    22,     0,    25,    26,    24,    49,    49,    50,
+       7,    25,    26,    25,    26,    25,    26,    25,    26,    25,
+      26,    25,    26,    25,    26,    25,    26,    25,    26,    25,
+      26,    24,    24,    24,    76,    77,    24,    24,    24,    24,
+      24,    24,    24,    24,    24,    20,    23,    20,    27,    23,
+      28,    27,    23,    23,    23,    23,    23,    23,    23,    23,
+      23,    20,    20,    20,    20,    27,    20,    20,    20,    20,
+      20,    20,    20,    20,    20,   117,    20,   119,    20,    68,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    48
+  };
+
+  const unsigned char
+  D4FunctionParser::yystos_[] =
+  {
+       0,    20,    41,    42,    43,    44,     0,    22,    24,    43,
+      20,    21,    27,    29,    30,    31,    32,    33,    34,    35,
+      36,    37,    38,    39,    43,    45,    46,    47,    48,    60,
+      61,    62,    63,    20,    62,    63,    24,    24,    24,    24,
+      24,    24,    24,    24,    24,    24,    24,    25,    26,    27,
+      28,    20,    49,    49,    49,    49,    49,    49,    49,    49,
+      49,    49,    49,    46,    62,    63,    63,    23,    23,    23,
+      23,    23,    23,    23,    23,    23,    23,    23,    20,    50,
+      50,    20,    51,    20,    52,    20,    53,    20,    54,    20,
+      55,    20,    56,    20,    57,    58,    62,    59,    62,    25,
+      26,    25,    25,    26,    25,    26,    25,    26,    25,    26,
+      25,    26,    25,    26,    25,    26,    25,    26,    25,    26,
+      20,    20,    20,    20,    20,    20,    20,    20,    62,    62
+  };
+
+  const unsigned char
+  D4FunctionParser::yyr1_[] =
+  {
+       0,    40,    41,    42,    42,    43,    44,    45,    45,    46,
+      46,    46,    47,    48,    48,    48,    48,    48,    48,    48,
+      48,    48,    48,    48,    49,    50,    50,    51,    51,    52,
+      52,    53,    53,    54,    54,    55,    55,    56,    56,    57,
+      57,    58,    58,    59,    59,    60,    60,    60,    61,    61,
+      62,    62,    63,    63
+  };
+
+  const unsigned char
+  D4FunctionParser::yyr2_[] =
+  {
+       0,     2,     1,     1,     3,     4,     1,     1,     3,     1,
+       1,     1,     1,     6,     6,     6,     6,     6,     6,     6,
+       6,     6,     6,     6,     1,     1,     3,     1,     3,     1,
+       3,     1,     3,     1,     3,     1,     3,     1,     3,     1,
+       3,     1,     3,     1,     3,     1,     2,     3,     2,     3,
+       1,     3,     1,     1
+  };
+
+
+
+  // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+  // First, the terminals, then, starting at \a yyntokens_, nonterminals.
+  const char*
+  const D4FunctionParser::yytname_[] =
+  {
+  "\"end of file\"", "error", "$undefined", "\"functions\"",
+  "\"arguments\"", "\"argument\"", "\"function\"", "\"function name\"",
+  "\"variable or constant\"", "\"array constant\"",
+  "\"fast byte arg list\"", "\"fast int8 arg list\"",
+  "\"fast uint16 arg list\"", "\"fast int16 arg list\"",
+  "\"fast uint32 arg list\"", "\"fast int32 arg list\"",
+  "\"fast uint64 arg list\"", "\"fast int64 arg list\"",
+  "\"fast float32 arg list\"", "\"fast float64 arg list\"", "\"word\"",
+  "\"string\"", "\";\"", "\":\"", "\"(\"", "\")\"", "\",\"", "\"/\"",
+  "\".\"", "\"$Byte\"", "\"$UInt8\"", "\"$Int8\"", "\"$UInt16\"",
+  "\"$Int16\"", "\"$UInt32\"", "\"$Int32\"", "\"$UInt64\"", "\"$Int64\"",
+  "\"$Float32\"", "\"$Float64\"", "$accept", "program", "functions",
+  "function", "fname", "args", "arg", "variable_or_constant",
+  "array_constant", "arg_length_hint", "fast_byte_arg_list",
+  "fast_int8_arg_list", "fast_uint16_arg_list", "fast_int16_arg_list",
+  "fast_uint32_arg_list", "fast_int32_arg_list", "fast_uint64_arg_list",
+  "fast_int64_arg_list", "fast_float32_arg_list", "fast_float64_arg_list",
+  "id", "group", "path", "name", YY_NULLPTR
+  };
+
+#if YYDEBUG
+  const unsigned short int
+  D4FunctionParser::yyrline_[] =
+  {
+       0,   155,   155,   161,   165,   172,   178,   190,   194,   201,
+     205,   209,   215,   227,   233,   239,   245,   251,   257,   263,
+     269,   275,   281,   287,   299,   305,   309,   316,   320,   327,
+     331,   338,   342,   349,   353,   359,   363,   370,   374,   381,
+     385,   395,   399,   406,   410,   417,   421,   426,   434,   439,
+     447,   451,   462,   466
+  };
+
+  // Print the state stack on the debug stream.
+  void
+  D4FunctionParser::yystack_print_ ()
+  {
+    *yycdebug_ << "Stack now";
+    for (stack_type::const_iterator
+           i = yystack_.begin (),
+           i_end = yystack_.end ();
+         i != i_end; ++i)
+      *yycdebug_ << ' ' << i->state;
+    *yycdebug_ << std::endl;
+  }
+
+  // Report on the debug stream that the rule \a yyrule is going to be reduced.
+  void
+  D4FunctionParser::yy_reduce_print_ (int yyrule)
+  {
+    unsigned int yylno = yyrline_[yyrule];
+    int yynrhs = yyr2_[yyrule];
+    // Print the symbols being reduced, and their result.
+    *yycdebug_ << "Reducing stack by rule " << yyrule - 1
+               << " (line " << yylno << "):" << std::endl;
+    // The symbols being reduced.
+    for (int yyi = 0; yyi < yynrhs; yyi++)
+      YY_SYMBOL_PRINT ("   $" << yyi + 1 << " =",
+                       yystack_[(yynrhs) - (yyi + 1)]);
+  }
+#endif // YYDEBUG
+
+  // Symbol number corresponding to token number t.
+  inline
+  D4FunctionParser::token_number_type
+  D4FunctionParser::yytranslate_ (int t)
+  {
+    static
+    const token_number_type
+    translate_table[] =
+    {
+     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,    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
+    };
+    const unsigned int user_token_number_max_ = 294;
+    const token_number_type undef_token_ = 2;
+
+    if (static_cast<int>(t) <= yyeof_)
+      return yyeof_;
+    else if (static_cast<unsigned int> (t) <= user_token_number_max_)
+      return translate_table[t];
+    else
+      return undef_token_;
+  }
+
+#line 34 "d4_function_parser.yy" // lalr1.cc:1157
+} // libdap
+#line 2423 "d4_function_parser.tab.cc" // lalr1.cc:1157
+#line 472 "d4_function_parser.yy" // lalr1.cc:1158
+
+
+// Forward the error to the driver for handling. The location parameter
+// provides the line number and character position of the error.
+void
+libdap::D4FunctionParser::error(const location_type &l, const std::string &m)
+{
+    evaluator.error(l, m);
+}
+
+/* include for access to scanner.yylex */
+#include "D4FunctionScanner.h"
+
+static int yylex(libdap::D4FunctionParser::semantic_type *yylval,
+                 libdap::location *loc,
+                 libdap::D4FunctionScanner &scanner,
+                 libdap::D4FunctionEvaluator &evaluator)
+{
+    if (evaluator.trace_scanning())
+        scanner.set_debug(true);
+    
+    return( scanner.yylex(yylval, loc) );
+}
diff --git a/d4_ce/d4_function_parser.tab.hh b/d4_ce/d4_function_parser.tab.hh
new file mode 100644
index 0000000..d716420
--- /dev/null
+++ b/d4_ce/d4_function_parser.tab.hh
@@ -0,0 +1,835 @@
+// A Bison parser, made by GNU Bison 3.0.1.
+
+// Skeleton interface for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file d4_function_parser.tab.hh
+ ** Define the libdap::parser class.
+ */
+
+// C++ LALR(1) parser skeleton written by Akim Demaille.
+
+#ifndef YY_YY_D4_FUNCTION_PARSER_TAB_HH_INCLUDED
+# define YY_YY_D4_FUNCTION_PARSER_TAB_HH_INCLUDED
+// //                    "%code requires" blocks.
+#line 47 "d4_function_parser.yy" // lalr1.cc:372
+
+
+#include "D4FunctionEvaluator.h"
+#include "D4RValue.h"
+#include "dods-datatypes.h"
+
+namespace libdap {
+    class D4FunctionScanner;
+}
+
+
+#line 56 "d4_function_parser.tab.hh" // lalr1.cc:372
+
+# include <cassert>
+# include <vector>
+# include <iostream>
+# include <stdexcept>
+# include <string>
+# include "stack.hh"
+# include "location.hh"
+#include <typeinfo>
+#ifndef YYASSERT
+# include <cassert>
+# define YYASSERT assert
+#endif
+
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# 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
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+
+#line 34 "d4_function_parser.yy" // lalr1.cc:372
+namespace libdap {
+#line 132 "d4_function_parser.tab.hh" // lalr1.cc:372
+
+
+
+  /// A char[S] buffer to store and retrieve objects.
+  ///
+  /// Sort of a variant, but does not keep track of the nature
+  /// of the stored data, since that knowledge is available
+  /// via the current state.
+  template <size_t S>
+  struct variant
+  {
+    /// Type of *this.
+    typedef variant<S> self_type;
+
+    /// Empty construction.
+    variant ()
+      : yytname_ (YY_NULLPTR)
+    {}
+
+    /// Construct and fill.
+    template <typename T>
+    variant (const T& t)
+      : yytname_ (typeid (T).name ())
+    {
+      YYASSERT (sizeof (T) <= S);
+      new (yyas_<T> ()) T (t);
+    }
+
+    /// Destruction, allowed only if empty.
+    ~variant ()
+    {
+      YYASSERT (!yytname_);
+    }
+
+    /// Instantiate an empty \a T in here.
+    template <typename T>
+    T&
+    build ()
+    {
+      YYASSERT (!yytname_);
+      YYASSERT (sizeof (T) <= S);
+      yytname_ = typeid (T).name ();
+      return *new (yyas_<T> ()) T;
+    }
+
+    /// Instantiate a \a T in here from \a t.
+    template <typename T>
+    T&
+    build (const T& t)
+    {
+      YYASSERT (!yytname_);
+      YYASSERT (sizeof (T) <= S);
+      yytname_ = typeid (T).name ();
+      return *new (yyas_<T> ()) T (t);
+    }
+
+    /// Accessor to a built \a T.
+    template <typename T>
+    T&
+    as ()
+    {
+      YYASSERT (yytname_ == typeid (T).name ());
+      YYASSERT (sizeof (T) <= S);
+      return *yyas_<T> ();
+    }
+
+    /// Const accessor to a built \a T (for %printer).
+    template <typename T>
+    const T&
+    as () const
+    {
+      YYASSERT (yytname_ == typeid (T).name ());
+      YYASSERT (sizeof (T) <= S);
+      return *yyas_<T> ();
+    }
+
+    /// Swap the content with \a other, of same type.
+    ///
+    /// Both variants must be built beforehand, because swapping the actual
+    /// data requires reading it (with as()), and this is not possible on
+    /// unconstructed variants: it would require some dynamic testing, which
+    /// should not be the variant's responsability.
+    /// Swapping between built and (possibly) non-built is done with
+    /// variant::move ().
+    template <typename T>
+    void
+    swap (self_type& other)
+    {
+      YYASSERT (yytname_);
+      YYASSERT (yytname_ == other.yytname_);
+      std::swap (as<T> (), other.as<T> ());
+    }
+
+    /// Move the content of \a other to this.
+    ///
+    /// Destroys \a other.
+    template <typename T>
+    void
+    move (self_type& other)
+    {
+      build<T> ();
+      swap<T> (other);
+      other.destroy<T> ();
+    }
+
+    /// Copy the content of \a other to this.
+    template <typename T>
+    void
+    copy (const self_type& other)
+    {
+      build<T> (other.as<T> ());
+    }
+
+    /// Destroy the stored \a T.
+    template <typename T>
+    void
+    destroy ()
+    {
+      as<T> ().~T ();
+      yytname_ = YY_NULLPTR;
+    }
+
+  private:
+    /// Prohibit blind copies.
+    self_type& operator=(const self_type&);
+    variant (const self_type&);
+
+    /// Accessor to raw memory as \a T.
+    template <typename T>
+    T*
+    yyas_ ()
+    {
+      void *yyp = yybuffer_.yyraw;
+      return static_cast<T*> (yyp);
+     }
+
+    /// Const accessor to raw memory as \a T.
+    template <typename T>
+    const T*
+    yyas_ () const
+    {
+      const void *yyp = yybuffer_.yyraw;
+      return static_cast<const T*> (yyp);
+     }
+
+    union
+    {
+      /// Strongest alignment constraints.
+      long double yyalign_me;
+      /// A buffer large enough to store any of the semantic values.
+      char yyraw[S];
+    } yybuffer_;
+
+    /// Whether the content is built: if defined, the name of the stored type.
+    const char *yytname_;
+  };
+
+
+  /// A Bison parser.
+  class D4FunctionParser
+  {
+  public:
+#ifndef YYSTYPE
+    /// An auxiliary type to compute the largest semantic type.
+    union union_type
+    {
+      // "function name"
+      // fname
+      char dummy1[sizeof(D4Function)];
+
+      // "argument"
+      // "function"
+      // "variable or constant"
+      // "array constant"
+      // function
+      // arg
+      // variable_or_constant
+      // array_constant
+      char dummy2[sizeof(D4RValue*)];
+
+      // "functions"
+      // "arguments"
+      // functions
+      // args
+      char dummy3[sizeof(D4RValueList*)];
+
+      // "word"
+      // "string"
+      // id
+      // group
+      // path
+      // name
+      char dummy4[sizeof(std::string)];
+
+      // "fast byte arg list"
+      // fast_byte_arg_list
+      char dummy5[sizeof(std::vector<dods_byte>*)];
+
+      // "fast float32 arg list"
+      // fast_float32_arg_list
+      char dummy6[sizeof(std::vector<dods_float32>*)];
+
+      // "fast float64 arg list"
+      // fast_float64_arg_list
+      char dummy7[sizeof(std::vector<dods_float64>*)];
+
+      // "fast int16 arg list"
+      // fast_int16_arg_list
+      char dummy8[sizeof(std::vector<dods_int16>*)];
+
+      // "fast int32 arg list"
+      // fast_int32_arg_list
+      char dummy9[sizeof(std::vector<dods_int32>*)];
+
+      // "fast int64 arg list"
+      // fast_int64_arg_list
+      char dummy10[sizeof(std::vector<dods_int64>*)];
+
+      // "fast int8 arg list"
+      // fast_int8_arg_list
+      char dummy11[sizeof(std::vector<dods_int8>*)];
+
+      // "fast uint16 arg list"
+      // fast_uint16_arg_list
+      char dummy12[sizeof(std::vector<dods_uint16>*)];
+
+      // "fast uint32 arg list"
+      // fast_uint32_arg_list
+      char dummy13[sizeof(std::vector<dods_uint32>*)];
+
+      // "fast uint64 arg list"
+      // fast_uint64_arg_list
+      char dummy14[sizeof(std::vector<dods_uint64>*)];
+};
+
+    /// Symbol semantic values.
+    typedef variant<sizeof(union_type)> semantic_type;
+#else
+    typedef YYSTYPE semantic_type;
+#endif
+    /// Symbol locations.
+    typedef location location_type;
+
+    /// Syntax errors thrown from user actions.
+    struct syntax_error : std::runtime_error
+    {
+      syntax_error (const location_type& l, const std::string& m);
+      location_type location;
+    };
+
+    /// Tokens.
+    struct token
+    {
+      enum yytokentype
+      {
+        END = 0,
+        WORD = 275,
+        STRING = 276,
+        SEMICOLON = 277,
+        COLON = 278,
+        LPAREN = 279,
+        RPAREN = 280,
+        COMMA = 281,
+        GROUP_SEP = 282,
+        PATH_SEP = 283,
+        DOLLAR_BYTE = 284,
+        DOLLAR_UINT8 = 285,
+        DOLLAR_INT8 = 286,
+        DOLLAR_UINT16 = 287,
+        DOLLAR_INT16 = 288,
+        DOLLAR_UINT32 = 289,
+        DOLLAR_INT32 = 290,
+        DOLLAR_UINT64 = 291,
+        DOLLAR_INT64 = 292,
+        DOLLAR_FLOAT32 = 293,
+        DOLLAR_FLOAT64 = 294
+      };
+    };
+
+    /// (External) token type, as returned by yylex.
+    typedef token::yytokentype token_type;
+
+    /// Internal symbol number.
+    typedef int symbol_number_type;
+
+    /// Internal symbol number for tokens (subsumed by symbol_number_type).
+    typedef unsigned char token_number_type;
+
+    /// A complete symbol.
+    ///
+    /// Expects its Base type to provide access to the symbol type
+    /// via type_get().
+    ///
+    /// Provide access to semantic value and location.
+    template <typename Base>
+    struct basic_symbol : Base
+    {
+      /// Alias to Base.
+      typedef Base super_type;
+
+      /// Default constructor.
+      basic_symbol ();
+
+      /// Copy constructor.
+      basic_symbol (const basic_symbol& other);
+
+      /// Constructor for valueless symbols, and symbols from each type.
+
+  basic_symbol (typename Base::kind_type t, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const D4Function v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const D4RValue* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const D4RValueList* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_byte>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_float32>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_float64>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_int16>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_int32>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_int64>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_int8>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_uint16>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_uint32>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_uint64>* v, const location_type& l);
+
+
+      /// Constructor for symbols with semantic value.
+      basic_symbol (typename Base::kind_type t,
+                    const semantic_type& v,
+                    const location_type& l);
+
+      ~basic_symbol ();
+
+      /// Destructive move, \a s is emptied into this.
+      void move (basic_symbol& s);
+
+      /// The semantic value.
+      semantic_type value;
+
+      /// The location.
+      location_type location;
+
+    private:
+      /// Assignment operator.
+      basic_symbol& operator= (const basic_symbol& other);
+    };
+
+    /// Type access provider for token (enum) based symbols.
+    struct by_type
+    {
+      /// Default constructor.
+      by_type ();
+
+      /// Copy constructor.
+      by_type (const by_type& other);
+
+      /// The symbol type as needed by the constructor.
+      typedef token_type kind_type;
+
+      /// Constructor from (external) token numbers.
+      by_type (kind_type t);
+
+      /// Steal the symbol type from \a that.
+      void move (by_type& that);
+
+      /// The (internal) type number (corresponding to \a type).
+      /// -1 when this symbol is empty.
+      symbol_number_type type_get () const;
+
+      /// The token.
+      token_type token () const;
+
+      enum { empty = 0 };
+
+      /// The symbol type.
+      /// -1 when this symbol is empty.
+      token_number_type type;
+    };
+
+    /// "External" symbols: returned by the scanner.
+    typedef basic_symbol<by_type> symbol_type;
+
+    // Symbol constructors declarations.
+    static inline
+    symbol_type
+    make_END (const location_type& l);
+
+    static inline
+    symbol_type
+    make_WORD (const std::string& v, const location_type& l);
+
+    static inline
+    symbol_type
+    make_STRING (const std::string& v, const location_type& l);
+
+    static inline
+    symbol_type
+    make_SEMICOLON (const location_type& l);
+
+    static inline
+    symbol_type
+    make_COLON (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LPAREN (const location_type& l);
+
+    static inline
+    symbol_type
+    make_RPAREN (const location_type& l);
+
+    static inline
+    symbol_type
+    make_COMMA (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GROUP_SEP (const location_type& l);
+
+    static inline
+    symbol_type
+    make_PATH_SEP (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_BYTE (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_UINT8 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_INT8 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_UINT16 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_INT16 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_UINT32 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_INT32 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_UINT64 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_INT64 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_FLOAT32 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_FLOAT64 (const location_type& l);
+
+
+    /// Build a parser object.
+    D4FunctionParser (D4FunctionScanner  &scanner_yyarg, D4FunctionEvaluator  &evaluator_yyarg);
+    virtual ~D4FunctionParser ();
+
+    /// Parse.
+    /// \returns  0 iff parsing succeeded.
+    virtual int parse ();
+
+#if YYDEBUG
+    /// The current debugging stream.
+    std::ostream& debug_stream () const YY_ATTRIBUTE_PURE;
+    /// Set the current debugging stream.
+    void set_debug_stream (std::ostream &);
+
+    /// Type for debugging levels.
+    typedef int debug_level_type;
+    /// The current debugging level.
+    debug_level_type debug_level () const YY_ATTRIBUTE_PURE;
+    /// Set the current debugging level.
+    void set_debug_level (debug_level_type l);
+#endif
+
+    /// Report a syntax error.
+    /// \param loc    where the syntax error is found.
+    /// \param msg    a description of the syntax error.
+    virtual void error (const location_type& loc, const std::string& msg);
+
+    /// Report a syntax error.
+    void error (const syntax_error& err);
+
+  private:
+    /// This class is not copyable.
+    D4FunctionParser (const D4FunctionParser&);
+    D4FunctionParser& operator= (const D4FunctionParser&);
+
+    /// State numbers.
+    typedef int state_type;
+
+    /// Generate an error message.
+    /// \param yystate   the state where the error occurred.
+    /// \param yytoken   the lookahead token type, or yyempty_.
+    virtual std::string yysyntax_error_ (state_type yystate,
+                                         symbol_number_type yytoken) const;
+
+    /// Compute post-reduction state.
+    /// \param yystate   the current state
+    /// \param yylhs     the nonterminal to push on the stack
+    state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
+
+    /// Whether the given \c yypact_ value indicates a defaulted state.
+    /// \param yyvalue   the value to check
+    static bool yy_pact_value_is_default_ (int yyvalue);
+
+    /// Whether the given \c yytable_ value indicates a syntax error.
+    /// \param yyvalue   the value to check
+    static bool yy_table_value_is_error_ (int yyvalue);
+
+    static const signed char yypact_ninf_;
+    static const signed char yytable_ninf_;
+
+    /// Convert a scanner token number \a t to a symbol number.
+    static token_number_type yytranslate_ (int t);
+
+    // Tables.
+  // YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+  // STATE-NUM.
+  static const signed char yypact_[];
+
+  // YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+  // Performed when YYTABLE does not specify something else to do.  Zero
+  // means the default is an error.
+  static const unsigned char yydefact_[];
+
+  // YYPGOTO[NTERM-NUM].
+  static const signed char yypgoto_[];
+
+  // YYDEFGOTO[NTERM-NUM].
+  static const signed char yydefgoto_[];
+
+  // YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+  // positive, shift that token.  If negative, reduce the rule whose
+  // number is the opposite.  If YYTABLE_NINF, syntax error.
+  static const short int yytable_[];
+
+  static const signed char yycheck_[];
+
+  // YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+  // symbol of state STATE-NUM.
+  static const unsigned char yystos_[];
+
+  // YYR1[YYN] -- Symbol number of symbol that rule YYN derives.
+  static const unsigned char yyr1_[];
+
+  // YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.
+  static const unsigned char yyr2_[];
+
+
+    /// Convert the symbol name \a n to a form suitable for a diagnostic.
+    static std::string yytnamerr_ (const char *n);
+
+
+    /// For a symbol, its name in clear.
+    static const char* const yytname_[];
+#if YYDEBUG
+  // YYRLINE[YYN] -- Source line where rule number YYN was defined.
+  static const unsigned short int yyrline_[];
+    /// Report on the debug stream that the rule \a r is going to be reduced.
+    virtual void yy_reduce_print_ (int r);
+    /// Print the state stack on the debug stream.
+    virtual void yystack_print_ ();
+
+    // Debugging.
+    int yydebug_;
+    std::ostream* yycdebug_;
+
+    /// \brief Display a symbol type, value and location.
+    /// \param yyo    The output stream.
+    /// \param yysym  The symbol.
+    template <typename Base>
+    void yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const;
+#endif
+
+    /// \brief Reclaim the memory associated to a symbol.
+    /// \param yymsg     Why this token is reclaimed.
+    ///                  If null, print nothing.
+    /// \param yysym     The symbol.
+    template <typename Base>
+    void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
+
+  private:
+    /// Type access provider for state based symbols.
+    struct by_state
+    {
+      /// Default constructor.
+      by_state ();
+
+      /// The symbol type as needed by the constructor.
+      typedef state_type kind_type;
+
+      /// Constructor.
+      by_state (kind_type s);
+
+      /// Copy constructor.
+      by_state (const by_state& other);
+
+      /// Steal the symbol type from \a that.
+      void move (by_state& that);
+
+      /// The (internal) type number (corresponding to \a state).
+      /// "empty" when empty.
+      symbol_number_type type_get () const;
+
+      enum { empty = 0 };
+
+      /// The state.
+      state_type state;
+    };
+
+    /// "Internal" symbol: element of the stack.
+    struct stack_symbol_type : basic_symbol<by_state>
+    {
+      /// Superclass.
+      typedef basic_symbol<by_state> super_type;
+      /// Construct an empty symbol.
+      stack_symbol_type ();
+      /// Steal the contents from \a sym to build this.
+      stack_symbol_type (state_type s, symbol_type& sym);
+      /// Assignment, needed by push_back.
+      stack_symbol_type& operator= (const stack_symbol_type& that);
+    };
+
+    /// Stack type.
+    typedef stack<stack_symbol_type> stack_type;
+
+    /// The stack.
+    stack_type yystack_;
+
+    /// Push a new state on the stack.
+    /// \param m    a debug message to display
+    ///             if null, no trace is output.
+    /// \param s    the symbol
+    /// \warning the contents of \a s.value is stolen.
+    void yypush_ (const char* m, stack_symbol_type& s);
+
+    /// Push a new look ahead token on the state on the stack.
+    /// \param m    a debug message to display
+    ///             if null, no trace is output.
+    /// \param s    the state
+    /// \param sym  the symbol (for its value and location).
+    /// \warning the contents of \a s.value is stolen.
+    void yypush_ (const char* m, state_type s, symbol_type& sym);
+
+    /// Pop \a n symbols the three stacks.
+    void yypop_ (unsigned int n = 1);
+
+    // Constants.
+    enum
+    {
+      yyeof_ = 0,
+      yylast_ = 117,     ///< Last index in yytable_.
+      yynnts_ = 24,  ///< Number of nonterminal symbols.
+      yyempty_ = -2,
+      yyfinal_ = 6, ///< Termination state number.
+      yyterror_ = 1,
+      yyerrcode_ = 256,
+      yyntokens_ = 40  ///< Number of tokens.
+    };
+
+
+    // User arguments.
+    D4FunctionScanner  &scanner;
+    D4FunctionEvaluator  &evaluator;
+  };
+
+
+#line 34 "d4_function_parser.yy" // lalr1.cc:372
+} // libdap
+#line 831 "d4_function_parser.tab.hh" // lalr1.cc:372
+
+
+
+
+#endif // !YY_YY_D4_FUNCTION_PARSER_TAB_HH_INCLUDED
diff --git a/d4_ce/d4_function_parser.yy b/d4_ce/d4_function_parser.yy
new file mode 100644
index 0000000..7269f13
--- /dev/null
+++ b/d4_ce/d4_function_parser.yy
@@ -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) 2014 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.
+
+%skeleton "lalr1.cc" /* -*- C++ -*- */
+%require "2.5"
+%defines
+
+// The d4_function_parser.tab.cc and .hh files define and declare this class
+%define parser_class_name {D4FunctionParser}
+
+// D4FunctionParser is in this namespace
+%define api.namespace {libdap}
+
+%define parse.trace
+%define parse.error verbose
+%define parse.assert
+
+// Could not get this to work with a C++ scanner built by flex. 8/10/13 jhrg
+// %define api.token.constructor
+%define api.value.type variant
+
+// Because the code uses the C++ mode of flex, we don't use this. 8/8/13 jhrg
+// %define api.prefix { d4_function_ }
+
+%code requires {
+
+#include "D4FunctionEvaluator.h"
+#include "D4RValue.h"
+#include "dods-datatypes.h"
+
+namespace libdap {
+    class D4FunctionScanner;
+}
+
+}
+
+// Pass both the scanner and parser objects to both the automatically generated
+// parser and scanner.
+%lex-param   { D4FunctionScanner  &scanner  }
+%parse-param { D4FunctionScanner  &scanner  }
+
+%lex-param   { D4FunctionEvaluator  &evaluator  }
+%parse-param { D4FunctionEvaluator  &evaluator  }
+
+%locations
+%initial-action
+{
+    // Initialize the initial location. This is printed when the parser builds
+    // its own error messages - when the parse fails as opposed to when the 
+    // function(s) name(s) a missing variable, ...
+
+    @$.initialize (evaluator.expression());
+};
+
+%code {
+    #include "BaseType.h"
+    #include "DMR.h"
+    #include "D4RValue.h"
+    #include "ServerFunctionsList.h"
+   
+    #include "parser-util.h"
+
+    /* include for all driver functions */
+    #include "D4FunctionEvaluator.h"
+
+    using namespace libdap ;
+    
+    /* this is silly, but I can't figure out a way around it */
+    static int yylex(libdap::D4FunctionParser::semantic_type *yylval,
+                     libdap::location *loc,
+                     libdap::D4FunctionScanner  &scanner,
+                     libdap::D4FunctionEvaluator   &evaluator);
+}
+
+%type <D4RValueList*> functions "functions"
+%type <D4RValueList*> args "arguments"
+
+%type <D4RValue*> arg "argument"
+%type <D4RValue*> function "function"
+
+%type <D4Function> fname "function name"
+%type <D4RValue*> variable_or_constant "variable or constant"
+%type <D4RValue*> array_constant "array constant"
+
+%type <std::vector<dods_byte>*> fast_byte_arg_list "fast byte arg list"
+%type <std::vector<dods_int8>*> fast_int8_arg_list "fast int8 arg list"
+%type <std::vector<dods_uint16>*> fast_uint16_arg_list "fast uint16 arg list"
+%type <std::vector<dods_int16>*> fast_int16_arg_list "fast int16 arg list"
+%type <std::vector<dods_uint32>*> fast_uint32_arg_list "fast uint32 arg list"
+%type <std::vector<dods_int32>*> fast_int32_arg_list "fast int32 arg list"
+%type <std::vector<dods_uint64>*> fast_uint64_arg_list "fast uint64 arg list"
+%type <std::vector<dods_int64>*> fast_int64_arg_list "fast int64 arg list"
+%type <std::vector<dods_float32>*> fast_float32_arg_list "fast float32 arg list"
+%type <std::vector<dods_float64>*> fast_float64_arg_list "fast float64 arg list"
+
+%type <std::string> id path group name
+
+// The strings used in the token definitions are used for error messages
+%token <std::string> WORD "word"
+%token <std::string> STRING "string"
+
+%token 
+    END  0  "end of file"
+    
+    SEMICOLON ";"
+    COLON ":"
+
+    LPAREN "("
+    RPAREN ")"
+    
+    COMMA ","
+
+    GROUP_SEP "/"
+    PATH_SEP "."
+    
+    DOLLAR_BYTE "$Byte"
+    DOLLAR_UINT8 "$UInt8"
+    DOLLAR_INT8 "$Int8"
+    DOLLAR_UINT16 "$UInt16"
+    DOLLAR_INT16 "$Int16"
+    DOLLAR_UINT32 "$UInt32"
+    DOLLAR_INT32 "$Int32"
+    DOLLAR_UINT64 "$UInt64"
+    DOLLAR_INT64 "$Int64"
+    DOLLAR_FLOAT32 "$Float32"
+    DOLLAR_FLOAT64 "$Float64"
+;
+
+%%
+
+%start program;
+
+program : functions 
+{ 
+    evaluator.set_result($1); 
+}
+;
+
+functions : function 
+{
+    $$ = new D4RValueList($1); 
+}
+| functions ";" function 
+{ 
+    $1->add_rvalue($3);
+    $$ = $1; 
+}
+;
+                    
+function : fname "(" args ")" 
+{ 
+    $$ = new D4RValue($1, $3); // Build a D4RValue from a D4Function pointer and a D4RValueList 
+} 
+;
+
+fname: WORD 
+{ 
+    D4Function f;
+    if (!evaluator.sf_list()->find_function($1, &f)) {
+        // ...cloud use @1.{first,last}_column in these error messages.
+        throw Error("'" + $1 + "' is not a registered DAP4 server function.");
+    }
+
+    $$ = f;
+}        
+;
+
+args: arg
+{ 
+    $$ = new D4RValueList($1); // build a D4RValueList from the D4RValue
+} 
+| args "," arg 
+{ 
+    $1->add_rvalue($3);
+    $$ = $1; // Append the D4RValue ($3) to the D4RValueList ($1), then return
+} 
+;
+
+arg: function
+{
+    $$ = $1;
+}
+| variable_or_constant
+{
+    $$ = $1;
+}
+| array_constant 
+{
+    $$ = $1;
+}
+;
+
+variable_or_constant : id
+{
+    D4RValue *rvalue = evaluator.build_rvalue($1);
+    if (!rvalue) {
+        throw Error("'" + $1 + "' is not a variable, number or string.");
+    }
+    
+    $$ = rvalue;
+}
+;
+  
+array_constant : 
+DOLLAR_BYTE "(" arg_length_hint ":" fast_byte_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_UINT8 "(" arg_length_hint ":" fast_byte_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_INT8 "(" arg_length_hint ":" fast_int8_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_UINT16 "(" arg_length_hint ":" fast_uint16_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_INT16 "(" arg_length_hint ":" fast_int16_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_UINT32 "(" arg_length_hint ":" fast_uint32_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_INT32 "(" arg_length_hint ":" fast_int32_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_UINT64 "(" arg_length_hint ":" fast_uint64_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_INT64 "(" arg_length_hint ":" fast_int64_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_FLOAT32 "(" arg_length_hint ":" fast_float32_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+|
+DOLLAR_FLOAT64 "(" arg_length_hint ":" fast_float64_arg_list ")"
+{
+    $$ = new D4RValue(*($5));
+    delete $5;
+}
+;
+
+/* Here the arg length hint is stored in the eval class so it can be used by the 
+   method that allocates the vector. The value is passed to vector::reserve().
+   This rule is run for it's side-effect only. This is also used to track the 
+   current arg number so that the hint can be used. */
+   
+arg_length_hint : WORD
+{
+    evaluator.set_arg_length_hint(get_ull($1.c_str()));
+}
+;
+
+fast_byte_arg_list: WORD
+{
+    $$ = evaluator.init_arg_list(dods_byte(strtol($1.c_str(), 0, 0)));
+}
+| fast_byte_arg_list "," WORD
+{
+    $1->push_back(strtol($3.c_str(), 0, 0));
+    $$ = $1;
+}
+;
+
+fast_int8_arg_list: WORD
+{
+    $$ = evaluator.init_arg_list(dods_int8(strtol($1.c_str(), 0, 0)));
+}
+| fast_int8_arg_list "," WORD
+{
+    $1->push_back(strtol($3.c_str(), 0, 0));
+    $$ = $1;
+}
+;
+
+fast_uint16_arg_list: WORD
+{
+    $$ = evaluator.init_arg_list(dods_uint16(strtol($1.c_str(), 0, 0)));
+}
+| fast_uint16_arg_list "," WORD
+{
+    $1->push_back(strtol($3.c_str(), 0, 0));
+    $$ = $1;
+}
+;
+
+fast_int16_arg_list: WORD
+{
+    $$ = evaluator.init_arg_list(dods_int16(strtol($1.c_str(), 0, 0)));
+}
+| fast_int16_arg_list "," WORD
+{
+    $1->push_back(strtol($3.c_str(), 0, 0));
+    $$ = $1;
+}
+;
+
+fast_uint32_arg_list: WORD
+{
+    $$ = evaluator.init_arg_list(dods_uint32(strtoul($1.c_str(), 0, 0)));
+}
+| fast_uint32_arg_list "," WORD
+{
+    $1->push_back(strtoul($3.c_str(), 0, 0));
+    $$ = $1;
+}
+;
+fast_int32_arg_list: WORD
+{
+    $$ = evaluator.init_arg_list(dods_int32(strtol($1.c_str(), 0, 0)));
+}
+| fast_int32_arg_list "," WORD
+{
+    $1->push_back(strtol($3.c_str(), 0, 0));
+    $$ = $1;
+}
+;
+
+fast_uint64_arg_list: WORD
+{
+    $$ = evaluator.init_arg_list(dods_uint64(strtoull($1.c_str(), 0, 0)));
+}
+| fast_uint64_arg_list "," WORD
+{
+    $1->push_back(strtoull($3.c_str(), 0, 0));
+    $$ = $1;
+}
+;
+
+fast_int64_arg_list: WORD
+{
+    $$ = evaluator.init_arg_list(dods_int64(strtoll($1.c_str(), 0, 0)));
+}
+| fast_int64_arg_list "," WORD
+{
+    $1->push_back(strtoll($3.c_str(), 0, 0));
+    $$ = $1;
+}
+;
+
+// I'm using path for the $Float constants so that tokens with dots will 
+// parse. I could add a FLOAT token, and I might have to do that later on
+// when filters are added to the CE, but this will work for now.
+fast_float32_arg_list: path
+{
+    $$ = evaluator.init_arg_list(dods_float32(strtof($1.c_str(), 0)));
+}
+| fast_float32_arg_list "," path
+{
+    $1->push_back(strtof($3.c_str(), 0));
+    $$ = $1;
+}
+;
+
+fast_float64_arg_list: path
+{
+    $$ = evaluator.init_arg_list(dods_float64(strtod($1.c_str(), 0)));
+}
+| fast_float64_arg_list "," path
+{
+    $1->push_back(strtod($3.c_str(), 0));
+    $$ = $1;
+}
+;
+
+id : path
+{
+    $$ = $1;
+}
+| "/" path
+{
+    $$.append("/");
+    $$.append($2);
+}
+| group "/" path
+{
+    $1.append("/");
+    $1.append($3);
+    $$ = $1;
+}
+;
+
+group : "/" name
+{
+    $$.append("/");
+    $$.append($2);
+}
+| group "/" name
+{
+    $1.append(".");
+    $1.append($3);
+    $$ = $1;
+}
+;
+
+path : name 
+{
+    $$ = $1;
+}
+| path "." name
+{
+    $1.append(".");
+    $1.append($3);
+    $$ = $1;
+}
+;
+
+// Because some formats/datasets allow 'any' name for a variable, it's possible
+// that a variable name will be a number, etc. The grammar also allows STRING
+// to support "name"."name with spaces and dots (.)".x
+name : WORD 
+{
+    $$=$1;
+}
+| STRING 
+{
+    $$=$1;
+}
+;
+
+%%
+
+// Forward the error to the driver for handling. The location parameter
+// provides the line number and character position of the error.
+void
+libdap::D4FunctionParser::error(const location_type &l, const std::string &m)
+{
+    evaluator.error(l, m);
+}
+
+/* include for access to scanner.yylex */
+#include "D4FunctionScanner.h"
+
+static int yylex(libdap::D4FunctionParser::semantic_type *yylval,
+                 libdap::location *loc,
+                 libdap::D4FunctionScanner &scanner,
+                 libdap::D4FunctionEvaluator &evaluator)
+{
+    if (evaluator.trace_scanning())
+        scanner.set_debug(true);
+    
+    return( scanner.yylex(yylval, loc) );
+}
diff --git a/d4_ce/d4_function_scanner.ll b/d4_ce/d4_function_scanner.ll
new file mode 100644
index 0000000..91d3509
--- /dev/null
+++ b/d4_ce/d4_function_scanner.ll
@@ -0,0 +1,184 @@
+
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2014 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++ -*- */
+
+//#include "config.h"
+
+#include <string>
+
+#include "D4FunctionScanner.h"
+
+/* typedef to make the returns for the tokens shorter */
+
+/* NB: It would be best to use the same scanner (and maybe parser) for
+   both the D4 CE and Function parameters, but for the initial version 
+   far less complexity is require by the Function expression scanner
+   (since the initial version will just support variables, constants, 
+   functions and the $<type> array special form) and not function arguments
+   that are general expressions (like array slicing and/or filters).
+   
+   This comment is here because this is the first place where there is 
+   coupling between the CE parser and its scanner. I'm not sure, however,
+   if one string can be parsed by two parsers if they are using two scanners,
+   so extending the Function parser to allow function args to be any CE 
+   clause may mean some more serious work with the parsers.
+   
+   jhrg 3/10/14 */
+typedef libdap::D4FunctionParser::token token;
+
+/* This was added because of some notes on the net about compiler version
+   issues. I don't know if it's needed when using the C++ mode of flex. */
+#undef yywrap
+#define yywrap() 1
+
+/* define yyterminate as this instead of NULL */
+#define yyterminate() return(token::END)
+
+%}
+
+%option c++
+%option yyclass="D4FunctionScanner"
+
+/* Use this if several scanners are needed. This will cause flex to
+   #define yyFlexLexer to be <prefix>FlexLexer (the yyFlexLexer is defined
+   in lex.<prefix>.cc. jhrg 8/8/13 */
+%option prefix="d4_function"
+
+/* These two options turn on line counting - useful for error messages - 
+   and debugging, respectively. When debugging is on, it's possible to see
+   which scanner rules are used at which points in the input. */
+%option yylineno
+%option debug
+
+/* Do not output the default rule (where any unmatched input is echoed to 
+   stdout). When set, nodefault will cause the scanner to exit on an error. */
+%option nodefault
+/* noyywrap makes the scanner assume that EOF/EOS is the end of the input.
+   If this is not set, the scanner will assume there are more files to 
+   scan. */ 
+%option noyywrap
+%option nounput
+/* When set, warn prints a message when the default rule can be matched
+   but nodefault is given (among other warnings). */
+%option warn
+
+%option batch
+
+%x quote
+
+/* This pattern is slightly different from the one used by the CE scanner
+   because it allows a WORD to start with a '#' so that the #<type> 
+   array constant syntax can be used in functions. Otherwise, a WORD must
+   be able to contain this hideous mix of characters because a variable 
+   can. jhrg 3/10/14 */
+WORD    [-+a-zA-Z0-9_%*\\~@!#][-+a-zA-Z0-9_%*\\~@!#]* 
+
+/* I added these tokens because floating point values may contain dots and
+   added a '.' to WORD will break the parsing of paths (or make for some 
+   fairly obscure code - where $Float32() takes tokens that match 'path'.
+   Since we have a separate scanner for the function expressions, might as
+   well add a FLOAT token... jhg 3/17/14 
+FLOAT   [-+eE.0-9][-+eE.0-9]*
+*/
+
+%{
+// Code run each time a pattern is matched
+#define YY_USER_ACTION loc->columns(yyleng);
+%}
+
+%%
+
+%{
+// Code run each time yylex is called
+loc->step();
+%}
+
+","		return token::COMMA;
+";"		return token::SEMICOLON;
+":"     return token::COLON;
+
+"("     return token::LPAREN;
+")"     return token::RPAREN;
+
+"/"     return token::GROUP_SEP;
+"."     return token::PATH_SEP;
+
+"$Byte" return token::DOLLAR_BYTE;
+"$UInt8" return token::DOLLAR_UINT8;
+"$Int8" return token::DOLLAR_INT8;
+"$UInt16" return token::DOLLAR_UINT16;
+"$Int16" return token::DOLLAR_INT16;
+"$UInt32" return token::DOLLAR_UINT32;
+"$Int32" return token::DOLLAR_INT32;
+"$UInt64" return token::DOLLAR_UINT64;
+"$Int64" return token::DOLLAR_INT64;
+"$Float32" return token::DOLLAR_FLOAT32;
+"$Float64" return token::DOLLAR_FLOAT64;
+
+[ \t]+  /* ignore these */
+
+[\r\n]+ /* ignore these */
+
+{WORD}  { yylval->build<std::string>(yytext); return token::WORD; }
+
+<INITIAL><<EOF>> return token::END;
+
+["]    { BEGIN(quote); yymore(); }
+
+<quote>[^"\\]*  yymore(); /* Anything that's not a double quote or a backslash */
+
+<quote>[\\]["]	yymore(); /* This matches the escaped double quote (\") */
+
+<quote>[\\]{2}  yymore(); /* This matches an escaped escape (\\) */
+
+<quote>[\\]{1}  {
+                    BEGIN(INITIAL);
+                    if (yytext) {
+                        YY_FATAL_ERROR("Inside a string, backslash (\\) can escape a double quote or must itself be escaped (\\\\).");
+                    }
+                }
+
+<quote>["]  { 
+                /* An unescaped double quote in the 'quote' state indicates the end of the string */
+                BEGIN(INITIAL); 
+                yylval->build<std::string>(yytext); 
+                return token::STRING;
+            }
+
+<quote><<EOF>>	{
+                  BEGIN(INITIAL);   /* resetting the state is needed for reentrant parsers */
+                  YY_FATAL_ERROR("Unterminated quote");
+                }
+
+.   {
+        BEGIN(INITIAL);
+        if (yytext) {
+            YY_FATAL_ERROR("Characters found in the input were not recognized.");
+        }
+    }
+%%
diff --git a/d4_ce/gen_grammar_sources/FlexLexer.h.tmp b/d4_ce/gen_grammar_sources/FlexLexer.h.tmp
new file mode 100644
index 0000000..a584303
--- /dev/null
+++ b/d4_ce/gen_grammar_sources/FlexLexer.h.tmp
@@ -0,0 +1,206 @@
+// -*-C++-*-
+// FlexLexer.h -- define interfaces for lexical analyzer classes generated
+// by flex
+
+// Copyright (c) 1993 The Regents of the University of California.
+// All rights reserved.
+//
+// This code is derived from software contributed to Berkeley by
+// Kent Williams and Tom Epperly.
+//
+//  Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions
+//  are met:
+
+//  1. Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//  2. Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+
+//  Neither the name of the University nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+//  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+//  PURPOSE.
+
+// This file defines FlexLexer, an abstract class which specifies the
+// external interface provided to flex C++ lexer objects, and yyFlexLexer,
+// which defines a particular lexer class.
+//
+// If you want to create multiple lexer classes, you use the -P flag
+// to rename each yyFlexLexer to some other xxFlexLexer.  You then
+// include <FlexLexer.h> in your other sources once per lexer class:
+//
+//	#undef yyFlexLexer
+//	#define yyFlexLexer xxFlexLexer
+//	#include <FlexLexer.h>
+//
+//	#undef yyFlexLexer
+//	#define yyFlexLexer zzFlexLexer
+//	#include <FlexLexer.h>
+//	...
+
+#ifndef __FLEX_LEXER_H
+// Never included before - need to define base class.
+#define __FLEX_LEXER_H
+
+#include <iostream>
+#  ifndef FLEX_STD
+#    define FLEX_STD std::
+#  endif
+
+extern "C++" {
+
+struct yy_buffer_state;
+typedef int yy_state_type;
+
+class FlexLexer {
+public:
+	virtual ~FlexLexer()	{ }
+
+	const char* YYText() const	{ return yytext; }
+	size_t YYLeng()	const	{ return yyleng; }
+
+	virtual void
+		yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
+	virtual struct yy_buffer_state*
+		yy_create_buffer( FLEX_STD istream* s, int size ) = 0;
+	virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
+	virtual void yyrestart( FLEX_STD istream* s ) = 0;
+
+	virtual int yylex() = 0;
+
+	// Call yylex with new input/output sources.
+	int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 )
+		{
+		switch_streams( new_in, new_out );
+		return yylex();
+		}
+
+	// Switch to new input/output streams.  A nil stream pointer
+	// indicates "keep the current one".
+	virtual void switch_streams( FLEX_STD istream* new_in = 0,
+					FLEX_STD ostream* new_out = 0 ) = 0;
+
+	int lineno() const		{ return yylineno; }
+
+	int debug() const		{ return yy_flex_debug; }
+	void set_debug( int flag )	{ yy_flex_debug = flag; }
+
+protected:
+	char* yytext;
+	size_t yyleng;
+	int yylineno;		// only maintained if you use %option yylineno
+	int yy_flex_debug;	// only has effect with -d or "%option debug"
+};
+
+}
+#endif // FLEXLEXER_H
+
+#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
+// Either this is the first time through (yyFlexLexerOnce not defined),
+// or this is a repeated include to define a different flavor of
+// yyFlexLexer, as discussed in the flex manual.
+#define yyFlexLexerOnce
+
+extern "C++" {
+
+class yyFlexLexer : public FlexLexer {
+public:
+	// arg_yyin and arg_yyout default to the cin and cout, but we
+	// only make that assignment when initializing in yylex().
+	yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 );
+
+	virtual ~yyFlexLexer();
+
+	void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
+	struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size );
+	void yy_delete_buffer( struct yy_buffer_state* b );
+	void yyrestart( FLEX_STD istream* s );
+
+	void yypush_buffer_state( struct yy_buffer_state* new_buffer );
+	void yypop_buffer_state();
+
+	virtual int yylex();
+	virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 );
+	virtual int yywrap();
+
+protected:
+	virtual size_t LexerInput( char* buf, size_t max_size );
+	virtual void LexerOutput( const char* buf, size_t size );
+	virtual void LexerError( const char* msg );
+
+	void yyunput( int c, char* buf_ptr );
+	int yyinput();
+
+	void yy_load_buffer_state();
+	void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s );
+	void yy_flush_buffer( struct yy_buffer_state* b );
+
+	int yy_start_stack_ptr;
+	int yy_start_stack_depth;
+	int* yy_start_stack;
+
+	void yy_push_state( int new_state );
+	void yy_pop_state();
+	int yy_top_state();
+
+	yy_state_type yy_get_previous_state();
+	yy_state_type yy_try_NUL_trans( yy_state_type current_state );
+	int yy_get_next_buffer();
+
+	FLEX_STD istream* yyin;	// input source for default LexerInput
+	FLEX_STD ostream* yyout;	// output sink for default LexerOutput
+
+	// yy_hold_char holds the character lost when yytext is formed.
+	char yy_hold_char;
+
+	// Number of characters read into yy_ch_buf.
+	size_t yy_n_chars;
+
+	// Points to current character in buffer.
+	char* yy_c_buf_p;
+
+	int yy_init;		// whether we need to initialize
+	int yy_start;		// start state number
+
+	// Flag which is used to allow yywrap()'s to do buffer switches
+	// instead of setting up a fresh yyin.  A bit of a hack ...
+	int yy_did_buffer_switch_on_eof;
+
+
+	size_t yy_buffer_stack_top; /**< index of top of stack. */
+	size_t yy_buffer_stack_max; /**< capacity of stack. */
+	struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */
+	void yyensure_buffer_stack(void);
+
+	// The following are not always needed, but may be depending
+	// on use of certain flex features (like REJECT or yymore()).
+
+	yy_state_type yy_last_accepting_state;
+	char* yy_last_accepting_cpos;
+
+	yy_state_type* yy_state_buf;
+	yy_state_type* yy_state_ptr;
+
+	char* yy_full_match;
+	int* yy_full_state;
+	int yy_full_lp;
+
+	int yy_lp;
+	int yy_looking_for_trail_begin;
+
+	int yy_more_flag;
+	int yy_more_len;
+	int yy_more_offset;
+	int yy_prev_more_offset;
+};
+
+}
+
+#endif // yyFlexLexer || ! yyFlexLexerOnce
+
diff --git a/d4_ce/gen_grammar_sources/d4_ce_parser.tab.cc.tmp b/d4_ce/gen_grammar_sources/d4_ce_parser.tab.cc.tmp
new file mode 100644
index 0000000..5649cb8
--- /dev/null
+++ b/d4_ce/gen_grammar_sources/d4_ce_parser.tab.cc.tmp
@@ -0,0 +1,1861 @@
+// A Bison parser, made by GNU Bison 3.0.
+
+// Skeleton implementation for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+
+// First part of user declarations.
+
+#line 37 "d4_ce_parser.tab.cc" // lalr1.cc:398
+
+# ifndef YY_NULL
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULL nullptr
+#  else
+#   define YY_NULL 0
+#  endif
+# endif
+
+#include "d4_ce_parser.tab.hh"
+
+// User implementation prologue.
+
+#line 51 "d4_ce_parser.tab.cc" // lalr1.cc:406
+// Unqualified %code blocks.
+#line 74 "d4_ce_parser.yy" // lalr1.cc:407
+
+   #include <iostream>
+   #include <cstdlib>
+   #include <fstream>
+   
+   #include "BaseType.h"
+   #include "DMR.h"
+   #include "D4Group.h"
+
+   /* include for all driver functions */
+   #include "D4ConstraintEvaluator.h"
+
+   /* this is silly, but I can't figure out a way around */
+   static int yylex(libdap::D4CEParser::semantic_type *yylval,
+                    libdap::location *loc,
+                    libdap::D4CEScanner  &scanner,
+                    libdap::D4ConstraintEvaluator   &driver);
+
+
+#line 73 "d4_ce_parser.tab.cc" // lalr1.cc:407
+
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> // FIXME: INFRINGES ON USER NAME SPACE.
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
+/* 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).  */
+
+# ifndef YYLLOC_DEFAULT
+#  define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                  \
+      if (N)                                                            \
+        {                                                               \
+          (Current).begin  = YYRHSLOC (Rhs, 1).begin;                   \
+          (Current).end    = YYRHSLOC (Rhs, N).end;                     \
+        }                                                               \
+      else                                                              \
+        {                                                               \
+          (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end;      \
+        }                                                               \
+    while (/*CONSTCOND*/ false)
+# endif
+
+
+// Suppress unused-variable warnings by "using" E.
+#define YYUSE(E) ((void) (E))
+
+// Enable debugging if requested.
+#if YYDEBUG
+
+// A pseudo ostream that takes yydebug_ into account.
+# define YYCDEBUG if (yydebug_) (*yycdebug_)
+
+# define YY_SYMBOL_PRINT(Title, Symbol)         \
+  do {                                          \
+    if (yydebug_)                               \
+    {                                           \
+      *yycdebug_ << Title << ' ';               \
+      yy_print_ (*yycdebug_, Symbol);           \
+      *yycdebug_ << std::endl;                  \
+    }                                           \
+  } while (false)
+
+# define YY_REDUCE_PRINT(Rule)          \
+  do {                                  \
+    if (yydebug_)                       \
+      yy_reduce_print_ (Rule);          \
+  } while (false)
+
+# define YY_STACK_PRINT()               \
+  do {                                  \
+    if (yydebug_)                       \
+      yystack_print_ ();                \
+  } while (false)
+
+#else // !YYDEBUG
+
+# define YYCDEBUG if (false) std::cerr
+# define YY_SYMBOL_PRINT(Title, Symbol)  YYUSE(Symbol)
+# define YY_REDUCE_PRINT(Rule)           static_cast<void>(0)
+# define YY_STACK_PRINT()                static_cast<void>(0)
+
+#endif // !YYDEBUG
+
+#define yyerrok         (yyerrstatus_ = 0)
+#define yyclearin       (yyempty = true)
+
+#define YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
+#define YYRECOVERING()  (!!yyerrstatus_)
+
+#line 35 "d4_ce_parser.yy" // lalr1.cc:473
+namespace libdap {
+#line 159 "d4_ce_parser.tab.cc" // lalr1.cc:473
+
+  /* Return 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.  */
+  std::string
+  D4CEParser::yytnamerr_ (const char *yystr)
+  {
+    if (*yystr == '"')
+      {
+        std::string yyr = "";
+        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:
+              yyr += *yyp;
+              break;
+
+            case '"':
+              return yyr;
+            }
+      do_not_strip_quotes: ;
+      }
+
+    return yystr;
+  }
+
+
+  /// Build a parser object.
+  D4CEParser::D4CEParser (D4CEScanner  &scanner_yyarg, D4ConstraintEvaluator  &driver_yyarg)
+    :
+#if YYDEBUG
+      yydebug_ (false),
+      yycdebug_ (&std::cerr),
+#endif
+      scanner (scanner_yyarg),
+      driver (driver_yyarg)
+  {}
+
+  D4CEParser::~D4CEParser ()
+  {}
+
+
+  /*---------------.
+  | Symbol types.  |
+  `---------------*/
+
+  inline
+  D4CEParser::syntax_error::syntax_error (const location_type& l, const std::string& m)
+    : std::runtime_error (m)
+    , location (l)
+  {}
+
+  // basic_symbol.
+  template <typename Base>
+  inline
+  D4CEParser::basic_symbol<Base>::basic_symbol ()
+    : value ()
+  {}
+
+  template <typename Base>
+  inline
+  D4CEParser::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
+    : Base (other)
+    , value ()
+    , location (other.location)
+  {
+      switch (other.type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.copy< bool > (other.value);
+        break;
+
+      case 38: // index
+        value.copy< libdap::D4ConstraintEvaluator::index > (other.value);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.copy< std::string > (other.value);
+        break;
+
+      default:
+        break;
+    }
+
+  }
+
+
+  template <typename Base>
+  inline
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const semantic_type& v, const location_type& l)
+    : Base (t)
+    , value ()
+    , location (l)
+  {
+    (void) v;
+      switch (this->type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.copy< bool > (v);
+        break;
+
+      case 38: // index
+        value.copy< libdap::D4ConstraintEvaluator::index > (v);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.copy< std::string > (v);
+        break;
+
+      default:
+        break;
+    }
+}
+
+
+  // Implementation of basic_symbol constructor for each type.
+
+  template <typename Base>
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const location_type& l)
+    : Base (t)
+    , value ()
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const bool v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const libdap::D4ConstraintEvaluator::index v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4CEParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+
+  template <typename Base>
+  inline
+  D4CEParser::basic_symbol<Base>::~basic_symbol ()
+  {
+    // User destructor.
+    symbol_number_type yytype = this->type_get ();
+    switch (yytype)
+    {
+   default:
+      break;
+    }
+
+    // Type destructor.
+    switch (yytype)
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.template destroy< bool > ();
+        break;
+
+      case 38: // index
+        value.template destroy< libdap::D4ConstraintEvaluator::index > ();
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.template destroy< std::string > ();
+        break;
+
+      default:
+        break;
+    }
+
+  }
+
+  template <typename Base>
+  inline
+  void
+  D4CEParser::basic_symbol<Base>::move (basic_symbol& s)
+  {
+    super_type::move(s);
+      switch (this->type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.move< bool > (s.value);
+        break;
+
+      case 38: // index
+        value.move< libdap::D4ConstraintEvaluator::index > (s.value);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.move< std::string > (s.value);
+        break;
+
+      default:
+        break;
+    }
+
+    location = s.location;
+  }
+
+  // by_type.
+  inline
+  D4CEParser::by_type::by_type ()
+     : type (empty)
+  {}
+
+  inline
+  D4CEParser::by_type::by_type (const by_type& other)
+    : type (other.type)
+  {}
+
+  inline
+  D4CEParser::by_type::by_type (token_type t)
+    : type (yytranslate_ (t))
+  {}
+
+  inline
+  void
+  D4CEParser::by_type::move (by_type& that)
+  {
+    type = that.type;
+    that.type = empty;
+  }
+
+  inline
+  int
+  D4CEParser::by_type::type_get () const
+  {
+    return type;
+  }
+  // Implementation of make_symbol for each symbol type.
+  D4CEParser::symbol_type
+  D4CEParser::make_END (const location_type& l)
+  {
+    return symbol_type (token::END, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_WORD (const std::string& v, const location_type& l)
+  {
+    return symbol_type (token::WORD, v, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_STRING (const std::string& v, const location_type& l)
+  {
+    return symbol_type (token::STRING, v, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_SEMICOLON (const location_type& l)
+  {
+    return symbol_type (token::SEMICOLON, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_PIPE (const location_type& l)
+  {
+    return symbol_type (token::PIPE, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LBRACKET (const location_type& l)
+  {
+    return symbol_type (token::LBRACKET, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_RBRACKET (const location_type& l)
+  {
+    return symbol_type (token::RBRACKET, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_COLON (const location_type& l)
+  {
+    return symbol_type (token::COLON, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LBRACE (const location_type& l)
+  {
+    return symbol_type (token::LBRACE, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_RBRACE (const location_type& l)
+  {
+    return symbol_type (token::RBRACE, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_COMMA (const location_type& l)
+  {
+    return symbol_type (token::COMMA, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_ND (const location_type& l)
+  {
+    return symbol_type (token::ND, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_ASSIGN (const location_type& l)
+  {
+    return symbol_type (token::ASSIGN, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LESS (const location_type& l)
+  {
+    return symbol_type (token::LESS, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_GREATER (const location_type& l)
+  {
+    return symbol_type (token::GREATER, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LESS_EQUAL (const location_type& l)
+  {
+    return symbol_type (token::LESS_EQUAL, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_GREATER_EQUAL (const location_type& l)
+  {
+    return symbol_type (token::GREATER_EQUAL, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_EQUAL (const location_type& l)
+  {
+    return symbol_type (token::EQUAL, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_NOT_EQUAL (const location_type& l)
+  {
+    return symbol_type (token::NOT_EQUAL, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_REGEX_MATCH (const location_type& l)
+  {
+    return symbol_type (token::REGEX_MATCH, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_LESS_BBOX (const location_type& l)
+  {
+    return symbol_type (token::LESS_BBOX, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_GREATER_BBOX (const location_type& l)
+  {
+    return symbol_type (token::GREATER_BBOX, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_MASK (const location_type& l)
+  {
+    return symbol_type (token::MASK, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_GROUP_SEP (const location_type& l)
+  {
+    return symbol_type (token::GROUP_SEP, l);
+
+  }
+
+  D4CEParser::symbol_type
+  D4CEParser::make_PATH_SEP (const location_type& l)
+  {
+    return symbol_type (token::PATH_SEP, l);
+
+  }
+
+
+
+  // by_state.
+  inline
+  D4CEParser::by_state::by_state ()
+    : state (empty)
+  {}
+
+  inline
+  D4CEParser::by_state::by_state (const by_state& other)
+    : state (other.state)
+  {}
+
+  inline
+  void
+  D4CEParser::by_state::move (by_state& that)
+  {
+    state = that.state;
+    that.state = empty;
+  }
+
+  inline
+  D4CEParser::by_state::by_state (state_type s)
+    : state (s)
+  {}
+
+  inline
+  D4CEParser::symbol_number_type
+  D4CEParser::by_state::type_get () const
+  {
+    return state == empty ? 0 : yystos_[state];
+  }
+
+  inline
+  D4CEParser::stack_symbol_type::stack_symbol_type ()
+  {}
+
+
+  inline
+  D4CEParser::stack_symbol_type::stack_symbol_type (state_type s, symbol_type& that)
+    : super_type (s, that.location)
+  {
+      switch (that.type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.move< bool > (that.value);
+        break;
+
+      case 38: // index
+        value.move< libdap::D4ConstraintEvaluator::index > (that.value);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.move< std::string > (that.value);
+        break;
+
+      default:
+        break;
+    }
+
+    // that is emptied.
+    that.type = empty;
+  }
+
+  inline
+  D4CEParser::stack_symbol_type&
+  D4CEParser::stack_symbol_type::operator= (const stack_symbol_type& that)
+  {
+    state = that.state;
+      switch (that.type_get ())
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        value.copy< bool > (that.value);
+        break;
+
+      case 38: // index
+        value.copy< libdap::D4ConstraintEvaluator::index > (that.value);
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        value.copy< std::string > (that.value);
+        break;
+
+      default:
+        break;
+    }
+
+    location = that.location;
+    return *this;
+  }
+
+
+  template <typename Base>
+  inline
+  void
+  D4CEParser::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
+  {
+    if (yymsg)
+      YY_SYMBOL_PRINT (yymsg, yysym);
+  }
+
+#if YYDEBUG
+  template <typename Base>
+  void
+  D4CEParser::yy_print_ (std::ostream& yyo,
+                                     const basic_symbol<Base>& yysym) const
+  {
+    std::ostream& yyoutput = yyo;
+    YYUSE (yyoutput);
+    symbol_number_type yytype = yysym.type_get ();
+    yyo << (yytype < yyntokens_ ? "token" : "nterm")
+        << ' ' << yytname_[yytype] << " ("
+        << yysym.location << ": ";
+    YYUSE (yytype);
+    yyo << ')';
+  }
+#endif
+
+  inline
+  void
+  D4CEParser::yypush_ (const char* m, state_type s, symbol_type& sym)
+  {
+    stack_symbol_type t (s, sym);
+    yypush_ (m, t);
+  }
+
+  inline
+  void
+  D4CEParser::yypush_ (const char* m, stack_symbol_type& s)
+  {
+    if (m)
+      YY_SYMBOL_PRINT (m, s);
+    yystack_.push (s);
+  }
+
+  inline
+  void
+  D4CEParser::yypop_ (unsigned int n)
+  {
+    yystack_.pop (n);
+  }
+
+#if YYDEBUG
+  std::ostream&
+  D4CEParser::debug_stream () const
+  {
+    return *yycdebug_;
+  }
+
+  void
+  D4CEParser::set_debug_stream (std::ostream& o)
+  {
+    yycdebug_ = &o;
+  }
+
+
+  D4CEParser::debug_level_type
+  D4CEParser::debug_level () const
+  {
+    return yydebug_;
+  }
+
+  void
+  D4CEParser::set_debug_level (debug_level_type l)
+  {
+    yydebug_ = l;
+  }
+#endif // YYDEBUG
+
+  inline D4CEParser::state_type
+  D4CEParser::yy_lr_goto_state_ (state_type yystate, int yylhs)
+  {
+    int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
+    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+      return yytable_[yyr];
+    else
+      return yydefgoto_[yylhs - yyntokens_];
+  }
+
+  inline bool
+  D4CEParser::yy_pact_value_is_default_ (int yyvalue)
+  {
+    return yyvalue == yypact_ninf_;
+  }
+
+  inline bool
+  D4CEParser::yy_table_value_is_error_ (int yyvalue)
+  {
+    return yyvalue == yytable_ninf_;
+  }
+
+  int
+  D4CEParser::parse ()
+  {
+    /// Whether yyla contains a lookahead.
+    bool yyempty = true;
+
+    // State.
+    int yyn;
+    int yylen = 0;
+
+    // Error handling.
+    int yynerrs_ = 0;
+    int yyerrstatus_ = 0;
+
+    /// The lookahead symbol.
+    symbol_type yyla;
+
+    /// The locations where the error started and ended.
+    stack_symbol_type yyerror_range[3];
+
+    /// $$ and @$.
+    stack_symbol_type yylhs;
+
+    /// The return value of parse ().
+    int yyresult;
+
+    // FIXME: This shoud be completely indented.  It is not yet to
+    // avoid gratuitous conflicts when merging into the master branch.
+    try
+      {
+    YYCDEBUG << "Starting parse" << std::endl;
+
+
+    // User initialization code.
+    #line 66 "d4_ce_parser.yy" // lalr1.cc:730
+{
+    // Initialize the initial location. This is printed when the parser builds
+    // its own error messages - when the parse fails as opposed to when the 
+    // CE names a missing variables, ...
+
+    yyla.location.initialize (driver.expression());
+}
+
+#line 896 "d4_ce_parser.tab.cc" // lalr1.cc:730
+
+    /* Initialize the stack.  The initial state will be set in
+       yynewstate, since the latter expects the semantical and the
+       location values to have been already stored, initialize these
+       stacks with a primary value.  */
+    yystack_.clear ();
+    yypush_ (YY_NULL, 0, yyla);
+
+    // A new symbol was pushed on the stack.
+  yynewstate:
+    YYCDEBUG << "Entering state " << yystack_[0].state << std::endl;
+
+    // Accept?
+    if (yystack_[0].state == yyfinal_)
+      goto yyacceptlab;
+
+    goto yybackup;
+
+    // Backup.
+  yybackup:
+
+    // Try to take a decision without lookahead.
+    yyn = yypact_[yystack_[0].state];
+    if (yy_pact_value_is_default_ (yyn))
+      goto yydefault;
+
+    // Read a lookahead token.
+    if (yyempty)
+      {
+        YYCDEBUG << "Reading a token: ";
+        try
+          {
+            yyla.type = yytranslate_ (yylex (&yyla.value, &yyla.location, scanner, driver));
+          }
+        catch (const syntax_error& yyexc)
+          {
+            error (yyexc);
+            goto yyerrlab1;
+          }
+        yyempty = false;
+      }
+    YY_SYMBOL_PRINT ("Next token is", yyla);
+
+    /* If the proper action on seeing token YYLA.TYPE is to reduce or
+       to detect an error, take that action.  */
+    yyn += yyla.type_get ();
+    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
+      goto yydefault;
+
+    // Reduce or error.
+    yyn = yytable_[yyn];
+    if (yyn <= 0)
+      {
+        if (yy_table_value_is_error_ (yyn))
+          goto yyerrlab;
+        yyn = -yyn;
+        goto yyreduce;
+      }
+
+    // Discard the token being shifted.
+    yyempty = true;
+
+    // Count tokens shifted since error; after three, turn off error status.
+    if (yyerrstatus_)
+      --yyerrstatus_;
+
+    // Shift the lookahead token.
+    yypush_ ("Shifting", yyn, yyla);
+    goto yynewstate;
+
+  /*-----------------------------------------------------------.
+  | yydefault -- do the default action for the current state.  |
+  `-----------------------------------------------------------*/
+  yydefault:
+    yyn = yydefact_[yystack_[0].state];
+    if (yyn == 0)
+      goto yyerrlab;
+    goto yyreduce;
+
+  /*-----------------------------.
+  | yyreduce -- Do a reduction.  |
+  `-----------------------------*/
+  yyreduce:
+    yylen = yyr2_[yyn];
+    yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);
+    /* Variants are always initialized to an empty instance of the
+       correct type. The default $$=$1 action is NOT applied when using
+       variants.  */
+      switch (yyr1_[yyn])
+    {
+      case 29: // dimensions
+      case 30: // dimension
+      case 31: // clauses
+      case 32: // clause
+      case 33: // subset
+      case 36: // indexes
+      case 39: // fields
+      case 40: // filter
+      case 41: // predicate
+        yylhs.value.build< bool > ();
+        break;
+
+      case 38: // index
+        yylhs.value.build< libdap::D4ConstraintEvaluator::index > ();
+        break;
+
+      case 3: // "word"
+      case 4: // "string"
+      case 43: // id
+      case 44: // group
+      case 45: // path
+      case 46: // name
+        yylhs.value.build< std::string > ();
+        break;
+
+      default:
+        break;
+    }
+
+
+    // Compute the default @$.
+    {
+      slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
+      YYLLOC_DEFAULT (yylhs.location, slice, yylen);
+    }
+
+    // Perform the reduction.
+    YY_REDUCE_PRINT (yyn);
+    try
+      {
+        switch (yyn)
+          {
+  case 2:
+#line 141 "d4_ce_parser.yy" // lalr1.cc:846
+    { driver.set_result(yystack_[0].value.as< bool > ()); }
+#line 1032 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 3:
+#line 142 "d4_ce_parser.yy" // lalr1.cc:846
+    { driver.set_result(yystack_[2].value.as< bool > () && yystack_[0].value.as< bool > ()); }
+#line 1038 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 4:
+#line 145 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = yystack_[0].value.as< bool > (); }
+#line 1044 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 5:
+#line 146 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = yystack_[2].value.as< bool > () && yystack_[0].value.as< bool > (); }
+#line 1050 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 6:
+#line 150 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< bool > () = driver.slice_dimension(yystack_[2].value.as< std::string > (), yystack_[0].value.as< libdap::D4ConstraintEvaluator::index > ());
+}
+#line 1058 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 7:
+#line 155 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = yystack_[0].value.as< bool > (); }
+#line 1064 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 8:
+#line 156 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = yystack_[2].value.as< bool > () && yystack_[0].value.as< bool > (); }
+#line 1070 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 9:
+#line 159 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = yystack_[0].value.as< bool > (); }
+#line 1076 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 10:
+#line 160 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = yystack_[2].value.as< bool > () && yystack_[0].value.as< bool > (); }
+#line 1082 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 11:
+#line 165 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var(yystack_[0].value.as< std::string > ());
+    }
+    else {
+        btp = driver.dmr()->root()->find_var(yystack_[0].value.as< std::string > ());
+    }
+    
+    if (!btp)
+        driver.throw_not_found(yystack_[0].value.as< std::string > (), "id");
+
+#if 0    
+    if (btp->type() == dods_array_c)
+        yylhs.value.as< bool > () = driver.mark_variable(btp) && driver.mark_array_variable(btp);   // handle array w/o slice ops
+    else
+#endif
+
+    yylhs.value.as< bool > () = driver.mark_variable(btp);
+}
+#line 1107 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 12:
+#line 187 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var(yystack_[1].value.as< std::string > ());
+    }
+    else {
+        btp = driver.dmr()->root()->find_var(yystack_[1].value.as< std::string > ());
+    }
+    
+    if (!btp)
+        driver.throw_not_found(yystack_[1].value.as< std::string > (), "id indexes");
+        
+    if (btp->type() != dods_array_c)
+        driver.throw_not_array(yystack_[1].value.as< std::string > (), "id indexes");
+        
+    yylhs.value.as< bool > () = driver.mark_variable(btp); //  && driver.mark_array_variable(btp);
+}
+#line 1129 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 13:
+#line 206 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var(yystack_[0].value.as< std::string > ());
+    }
+    else {
+        btp = driver.dmr()->root()->find_var(yystack_[0].value.as< std::string > ());
+    }
+
+    if (!btp)
+        driver.throw_not_found(yystack_[0].value.as< std::string > (), "id fields");
+    
+    if (btp->type() == dods_array_c) {
+        if (btp->var() && !btp->var()->is_constructor_type())
+            throw Error("The variable " + yystack_[0].value.as< std::string > () + " must be a Structure or Sequence to be used with {}.");
+            
+        // This call also tests the btp to make sure it's an array
+        driver.mark_array_variable(btp);
+    }
+    else {
+        // Don't mark the variable here because only some fields are to be sent and those
+        // will be marked when the fields are parsed
+        if (!btp->is_constructor_type())
+            throw Error("The variable " + yystack_[0].value.as< std::string > () + " must be a Structure or Sequence to be used with {}.");
+    }
+    
+    // push the basetype (a ctor or array of ctor) on the stack so that it is
+    // accessible while the fields are being parsed
+    driver.push_basetype(btp);
+}
+#line 1164 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 14:
+#line 237 "d4_ce_parser.yy" // lalr1.cc:846
+    { 
+    driver.pop_basetype(); 
+    yylhs.value.as< bool > () = true; 
+}
+#line 1173 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 15:
+#line 243 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    BaseType *btp = 0;
+    if (driver.top_basetype()) {
+        btp = driver.top_basetype()->var(yystack_[1].value.as< std::string > ());
+    }
+    else {
+        btp = driver.dmr()->root()->find_var(yystack_[1].value.as< std::string > ());
+    }
+
+    if (!btp)
+        driver.throw_not_found(yystack_[1].value.as< std::string > (), "id indexes fields");
+    
+    if (btp->type() != dods_array_c)
+        driver.throw_not_array(yystack_[1].value.as< std::string > (), "id indexes fields");
+
+    // This call also tests the btp to make sure it's an array
+    driver.mark_array_variable(btp);
+    
+    if (!btp->var()->is_constructor_type())
+        throw Error("The variable " + yystack_[1].value.as< std::string > () + " must be a Structure or Sequence to be used with {}.");
+      
+    driver.push_basetype(btp->var());       
+}
+#line 1201 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 16:
+#line 267 "d4_ce_parser.yy" // lalr1.cc:846
+    { 
+    driver.pop_basetype();
+    yylhs.value.as< bool > () = true; 
+}
+#line 1210 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 17:
+#line 279 "d4_ce_parser.yy" // lalr1.cc:846
+    { 
+    driver.push_index(yystack_[0].value.as< libdap::D4ConstraintEvaluator::index > ()); 
+    yylhs.value.as< bool > () = true; 
+}
+#line 1219 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 18:
+#line 283 "d4_ce_parser.yy" // lalr1.cc:846
+    { driver.push_index(yystack_[0].value.as< libdap::D4ConstraintEvaluator::index > ()); }
+#line 1225 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 19:
+#line 283 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = yystack_[0].value.as< bool > (); }
+#line 1231 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 20:
+#line 286 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(); }
+#line 1237 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 21:
+#line 287 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[1].value.as< std::string > ()); }
+#line 1243 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 22:
+#line 288 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[3].value.as< std::string > (), 1, yystack_[1].value.as< std::string > ()); }
+#line 1249 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 23:
+#line 289 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[5].value.as< std::string > (), yystack_[3].value.as< std::string > (), yystack_[1].value.as< std::string > ()); }
+#line 1255 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 24:
+#line 290 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[2].value.as< std::string > (), 1); }
+#line 1261 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 25:
+#line 291 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< libdap::D4ConstraintEvaluator::index > () = driver.make_index(yystack_[4].value.as< std::string > (), yystack_[2].value.as< std::string > ()); }
+#line 1267 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 26:
+#line 294 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = yystack_[1].value.as< bool > (); }
+#line 1273 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 29:
+#line 311 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = true; }
+#line 1279 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 30:
+#line 312 "d4_ce_parser.yy" // lalr1.cc:846
+    { yylhs.value.as< bool > () = true; }
+#line 1285 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 42:
+#line 334 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > () = yystack_[0].value.as< std::string > ();
+}
+#line 1293 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 43:
+#line 338 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > ().append("/");
+    yylhs.value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+}
+#line 1302 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 44:
+#line 343 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::string > ().append("/");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1312 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 45:
+#line 351 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > ().append("/");
+    yylhs.value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+}
+#line 1321 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 46:
+#line 356 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::string > ().append(".");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1331 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 47:
+#line 364 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > () = yystack_[0].value.as< std::string > ();
+}
+#line 1339 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 48:
+#line 368 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::string > ().append(".");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1349 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 49:
+#line 379 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > ()=yystack_[0].value.as< std::string > ();
+}
+#line 1357 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 50:
+#line 383 "d4_ce_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > ()=yystack_[0].value.as< std::string > ();
+}
+#line 1365 "d4_ce_parser.tab.cc" // lalr1.cc:846
+    break;
+
+
+#line 1369 "d4_ce_parser.tab.cc" // lalr1.cc:846
+          default:
+            break;
+          }
+      }
+    catch (const syntax_error& yyexc)
+      {
+        error (yyexc);
+        YYERROR;
+      }
+    YY_SYMBOL_PRINT ("-> $$ =", yylhs);
+    yypop_ (yylen);
+    yylen = 0;
+    YY_STACK_PRINT ();
+
+    // Shift the result of the reduction.
+    yypush_ (YY_NULL, yylhs);
+    goto yynewstate;
+
+  /*--------------------------------------.
+  | yyerrlab -- here on detecting error.  |
+  `--------------------------------------*/
+  yyerrlab:
+    // If not already recovering from an error, report this error.
+    if (!yyerrstatus_)
+      {
+        ++yynerrs_;
+        error (yyla.location, yysyntax_error_ (yystack_[0].state,
+                                           yyempty ? yyempty_ : yyla.type_get ()));
+      }
+
+
+    yyerror_range[1].location = yyla.location;
+    if (yyerrstatus_ == 3)
+      {
+        /* If just tried and failed to reuse lookahead token after an
+           error, discard it.  */
+
+        // Return failure if at end of input.
+        if (yyla.type_get () == yyeof_)
+          YYABORT;
+        else if (!yyempty)
+          {
+            yy_destroy_ ("Error: discarding", yyla);
+            yyempty = true;
+          }
+      }
+
+    // Else will try to reuse lookahead 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 (false)
+      goto yyerrorlab;
+    yyerror_range[1].location = yystack_[yylen - 1].location;
+    /* $$ was initialized before running the user action.  */
+    YY_SYMBOL_PRINT ("Error: discarding", yylhs);
+    yylhs.~stack_symbol_type();
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYERROR.  */
+    yypop_ (yylen);
+    yylen = 0;
+    goto yyerrlab1;
+
+  /*-------------------------------------------------------------.
+  | yyerrlab1 -- common code for both syntax error and YYERROR.  |
+  `-------------------------------------------------------------*/
+  yyerrlab1:
+    yyerrstatus_ = 3;   // Each real token shifted decrements this.
+    {
+      stack_symbol_type error_token;
+      for (;;)
+        {
+          yyn = yypact_[yystack_[0].state];
+          if (!yy_pact_value_is_default_ (yyn))
+            {
+              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 (yystack_.size () == 1)
+            YYABORT;
+
+          yyerror_range[1].location = yystack_[0].location;
+          yy_destroy_ ("Error: popping", yystack_[0]);
+          yypop_ ();
+          YY_STACK_PRINT ();
+        }
+
+      yyerror_range[2].location = yyla.location;
+      YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);
+
+      // Shift the error token.
+      error_token.state = yyn;
+      yypush_ ("Shifting", error_token);
+    }
+    goto yynewstate;
+
+    // Accept.
+  yyacceptlab:
+    yyresult = 0;
+    goto yyreturn;
+
+    // Abort.
+  yyabortlab:
+    yyresult = 1;
+    goto yyreturn;
+
+  yyreturn:
+    if (!yyempty)
+      yy_destroy_ ("Cleanup: discarding lookahead", yyla);
+
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYABORT or YYACCEPT.  */
+    yypop_ (yylen);
+    while (1 < yystack_.size ())
+      {
+        yy_destroy_ ("Cleanup: popping", yystack_[0]);
+        yypop_ ();
+      }
+
+    return yyresult;
+  }
+    catch (...)
+      {
+        YYCDEBUG << "Exception caught: cleaning lookahead and stack"
+                 << std::endl;
+        // Do not try to display the values of the reclaimed symbols,
+        // as their printer might throw an exception.
+        if (!yyempty)
+          yy_destroy_ (YY_NULL, yyla);
+
+        while (1 < yystack_.size ())
+          {
+            yy_destroy_ (YY_NULL, yystack_[0]);
+            yypop_ ();
+          }
+        throw;
+      }
+  }
+
+  void
+  D4CEParser::error (const syntax_error& yyexc)
+  {
+    error (yyexc.location, yyexc.what());
+  }
+
+  // Generate an error message.
+  std::string
+  D4CEParser::yysyntax_error_ (state_type yystate, symbol_number_type yytoken) const
+  {
+    std::string yyres;
+    // Number of reported tokens (one for the "unexpected", one per
+    // "expected").
+    size_t yycount = 0;
+    // Its maximum.
+    enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+    // Arguments of yyformat.
+    char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+
+    /* There are many possibilities here to consider:
+       - If this state is a consistent state with a default action, then
+         the only way this function was invoked is if the default action
+         is an error action.  In that case, don't check for expected
+         tokens because there are none.
+       - The only way there can be no lookahead present (in yytoken) is
+         if this state is a consistent state with a default action.
+         Thus, detecting the absence of a lookahead is sufficient to
+         determine that there is no unexpected or expected token to
+         report.  In that case, just report a simple "syntax error".
+       - Don't assume there isn't a lookahead just because this state is
+         a consistent state with a default action.  There might have
+         been a previous inconsistent state, consistent state with a
+         non-default action, or user semantic action that manipulated
+         yyla.  (However, yyla is currently not documented for users.)
+       - Of course, the expected token list depends on states to have
+         correct lookahead information, and it depends on the parser not
+         to perform extra reductions after fetching a lookahead from the
+         scanner and before detecting a syntax error.  Thus, state
+         merging (from LALR or IELR) and default reductions corrupt the
+         expected token list.  However, the list is correct for
+         canonical LR with one exception: it will still contain any
+         token that will not be accepted due to an error action in a
+         later state.
+    */
+    if (yytoken != yyempty_)
+      {
+        yyarg[yycount++] = yytname_[yytoken];
+        int yyn = yypact_[yystate];
+        if (!yy_pact_value_is_default_ (yyn))
+          {
+            /* Start YYX at -YYN if negative to avoid negative indexes in
+               YYCHECK.  In other words, skip the first -YYN actions for
+               this state because they are default actions.  */
+            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_;
+            for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+              if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
+                  && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
+                {
+                  if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                    {
+                      yycount = 1;
+                      break;
+                    }
+                  else
+                    yyarg[yycount++] = yytname_[yyx];
+                }
+          }
+      }
+
+    char const* yyformat = YY_NULL;
+    switch (yycount)
+      {
+#define YYCASE_(N, S)                         \
+        case N:                               \
+          yyformat = S;                       \
+        break
+        YYCASE_(0, YY_("syntax error"));
+        YYCASE_(1, YY_("syntax error, unexpected %s"));
+        YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+        YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+        YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+        YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+#undef YYCASE_
+      }
+
+    // Argument number.
+    size_t yyi = 0;
+    for (char const* yyp = yyformat; *yyp; ++yyp)
+      if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
+        {
+          yyres += yytnamerr_ (yyarg[yyi++]);
+          ++yyp;
+        }
+      else
+        yyres += *yyp;
+    return yyres;
+  }
+
+
+  const signed char D4CEParser::yypact_ninf_ = -19;
+
+  const signed char D4CEParser::yytable_ninf_ = -47;
+
+  const signed char
+  D4CEParser::yypact_[] =
+  {
+       2,   -19,   -19,    17,    22,    28,   -19,    43,   -19,    -2,
+      21,    18,    16,   -19,    16,    27,   -19,     2,     2,     2,
+      29,    46,    44,    45,    49,    17,    17,   -19,    43,   -19,
+      34,    47,   -19,    -6,    38,   -19,   -19,     2,   -19,    44,
+      46,    16,    32,   -19,     2,   -19,   -19,   -19,   -19,   -19,
+     -19,   -19,   -19,   -19,   -19,   -19,     2,   -19,    31,    25,
+     -19,   -19,   -19,    -6,    42,   -19,   -19,     2,   -19,    37,
+     -19,    50,   -19,   -19
+  };
+
+  const unsigned char
+  D4CEParser::yydefact_[] =
+  {
+       0,    49,    50,     0,     0,     0,     4,     2,     7,     9,
+      11,     0,    42,    47,    43,    47,     1,     0,     0,     0,
+       0,     0,     0,    12,    17,     0,     0,     5,     3,     8,
+      11,    10,    27,     0,     0,    20,     6,     0,    14,     0,
+       0,    44,    47,    48,     0,    41,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,     0,    21,     0,     0,
+      16,    19,    28,    29,     0,    24,    26,     0,    22,     0,
+      30,     0,    25,    23
+  };
+
+  const signed char
+  D4CEParser::yypgoto_[] =
+  {
+     -19,   -19,   -19,    48,   -14,    51,   -19,   -19,   -19,    20,
+     -19,    40,    23,   -19,    19,     1,   -18,   -19,     4,    -1
+  };
+
+  const signed char
+  D4CEParser::yydefgoto_[] =
+  {
+      -1,     4,     5,     6,     7,     8,     9,    22,    39,    23,
+      40,    24,    38,    31,    32,    56,    10,    11,    12,    13
+  };
+
+  const signed char
+  D4CEParser::yytable_[] =
+  {
+      30,    33,    15,    28,    19,     1,     2,    14,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    30,
+       1,     2,    16,    59,    42,    43,    33,     3,    20,    41,
+      18,   -13,    34,    17,    64,    21,    66,    35,    63,    65,
+      71,    20,    26,    25,   -13,    72,    57,    58,    18,    70,
+      68,    69,   -45,    20,    37,   -15,   -18,   -46,    73,    44,
+      61,    36,    60,    62,    67,    27,     0,     0,     0,    29
+  };
+
+  const signed char
+  D4CEParser::yycheck_[] =
+  {
+      18,    19,     3,    17,     6,     3,     4,     3,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,    23,    24,    37,
+       3,     4,     0,    37,    25,    26,    44,    25,     7,    25,
+       5,    10,     3,     5,     3,    14,    11,     8,    56,     8,
+       3,     7,    26,    25,    10,     8,     8,     9,     5,    67,
+       8,     9,    25,     7,    10,    10,     7,    25,     8,    12,
+      40,    21,    39,    44,    63,    17,    -1,    -1,    -1,    18
+  };
+
+  const unsigned char
+  D4CEParser::yystos_[] =
+  {
+       0,     3,     4,    25,    28,    29,    30,    31,    32,    33,
+      43,    44,    45,    46,    45,    46,     0,     5,     5,     6,
+       7,    14,    34,    36,    38,    25,    26,    30,    31,    32,
+      43,    40,    41,    43,     3,     8,    38,    10,    39,    35,
+      37,    45,    46,    46,    12,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    42,     8,     9,    31,
+      39,    36,    41,    43,     3,     8,    11,    42,     8,     9,
+      43,     3,     8,     8
+  };
+
+  const unsigned char
+  D4CEParser::yyr1_[] =
+  {
+       0,    27,    28,    28,    29,    29,    30,    31,    31,    32,
+      32,    33,    33,    34,    33,    35,    33,    36,    37,    36,
+      38,    38,    38,    38,    38,    38,    39,    40,    40,    41,
+      41,    42,    42,    42,    42,    42,    42,    42,    42,    42,
+      42,    42,    43,    43,    43,    44,    44,    45,    45,    46,
+      46
+  };
+
+  const unsigned char
+  D4CEParser::yyr2_[] =
+  {
+       0,     2,     1,     3,     1,     3,     3,     1,     3,     1,
+       3,     1,     2,     0,     3,     0,     4,     1,     0,     3,
+       2,     3,     5,     7,     4,     6,     3,     1,     3,     3,
+       5,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     2,     3,     2,     3,     1,     3,     1,
+       1
+  };
+
+
+
+  // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+  // First, the terminals, then, starting at \a yyntokens_, nonterminals.
+  const char*
+  const D4CEParser::yytname_[] =
+  {
+  "\"end of file\"", "error", "$undefined", "\"word\"", "\"string\"",
+  "\";\"", "\"|\"", "\"[\"", "\"]\"", "\":\"", "\"{\"", "\"}\"", "\",\"",
+  "\"ND\"", "\"=\"", "\"<\"", "\">\"", "\"<=\"", "\">=\"", "\"==\"",
+  "\"!=\"", "\"~=\"", "\"<<\"", "\">>\"", "\"@=\"", "\"/\"", "\".\"",
+  "$accept", "expression", "dimensions", "dimension", "clauses", "clause",
+  "subset", "$@1", "$@2", "indexes", "$@3", "index", "fields", "filter",
+  "predicate", "op", "id", "group", "path", "name", YY_NULL
+  };
+
+#if YYDEBUG
+  const unsigned short int
+  D4CEParser::yyrline_[] =
+  {
+       0,   141,   141,   142,   145,   146,   149,   155,   156,   159,
+     160,   164,   186,   206,   205,   243,   242,   278,   283,   283,
+     286,   287,   288,   289,   290,   291,   294,   297,   298,   311,
+     312,   317,   318,   319,   320,   321,   322,   323,   325,   326,
+     328,   330,   333,   337,   342,   350,   355,   363,   367,   378,
+     382
+  };
+
+  // Print the state stack on the debug stream.
+  void
+  D4CEParser::yystack_print_ ()
+  {
+    *yycdebug_ << "Stack now";
+    for (stack_type::const_iterator
+           i = yystack_.begin (),
+           i_end = yystack_.end ();
+         i != i_end; ++i)
+      *yycdebug_ << ' ' << i->state;
+    *yycdebug_ << std::endl;
+  }
+
+  // Report on the debug stream that the rule \a yyrule is going to be reduced.
+  void
+  D4CEParser::yy_reduce_print_ (int yyrule)
+  {
+    unsigned int yylno = yyrline_[yyrule];
+    int yynrhs = yyr2_[yyrule];
+    // Print the symbols being reduced, and their result.
+    *yycdebug_ << "Reducing stack by rule " << yyrule - 1
+               << " (line " << yylno << "):" << std::endl;
+    // The symbols being reduced.
+    for (int yyi = 0; yyi < yynrhs; yyi++)
+      YY_SYMBOL_PRINT ("   $" << yyi + 1 << " =",
+                       yystack_[(yynrhs) - (yyi + 1)]);
+  }
+#endif // YYDEBUG
+
+  // Symbol number corresponding to token number t.
+  inline
+  D4CEParser::token_number_type
+  D4CEParser::yytranslate_ (int t)
+  {
+    static
+    const token_number_type
+    translate_table[] =
+    {
+     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,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26
+    };
+    const unsigned int user_token_number_max_ = 281;
+    const token_number_type undef_token_ = 2;
+
+    if (static_cast<int>(t) <= yyeof_)
+      return yyeof_;
+    else if (static_cast<unsigned int> (t) <= user_token_number_max_)
+      return translate_table[t];
+    else
+      return undef_token_;
+  }
+
+#line 35 "d4_ce_parser.yy" // lalr1.cc:1156
+} // libdap
+#line 1838 "d4_ce_parser.tab.cc" // lalr1.cc:1156
+#line 388 "d4_ce_parser.yy" // lalr1.cc:1157
+
+
+// Forward the error to the driver for handling. The location parameter
+// provides the line number and character position of the error.
+void
+libdap::D4CEParser::error(const location_type &l, const std::string &m)
+{
+    driver.error(l, m);
+}
+
+/* include for access to scanner.yylex */
+#include "D4CEScanner.h"
+
+static int yylex(libdap::D4CEParser::semantic_type *yylval,
+                 libdap::location *loc,
+                 libdap::D4CEScanner &scanner,
+                 libdap::D4ConstraintEvaluator &driver)
+{
+    if (driver.trace_scanning())
+        scanner.set_debug(true);
+    
+    return( scanner.yylex(yylval, loc) );
+}
diff --git a/d4_ce/gen_grammar_sources/d4_ce_parser.tab.hh.tmp b/d4_ce/gen_grammar_sources/d4_ce_parser.tab.hh.tmp
new file mode 100644
index 0000000..dc3ac3e
--- /dev/null
+++ b/d4_ce/gen_grammar_sources/d4_ce_parser.tab.hh.tmp
@@ -0,0 +1,731 @@
+// A Bison parser, made by GNU Bison 3.0.
+
+// Skeleton interface for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file d4_ce_parser.tab.hh
+ ** Define the libdap::parser class.
+ */
+
+// C++ LALR(1) parser skeleton written by Akim Demaille.
+
+#ifndef YY_YY_D4_CE_PARSER_TAB_HH_INCLUDED
+# define YY_YY_D4_CE_PARSER_TAB_HH_INCLUDED
+// //                    "%code requires" blocks.
+#line 48 "d4_ce_parser.yy" // lalr1.cc:386
+
+#include "D4ConstraintEvaluator.h"
+namespace libdap {
+    class D4CEScanner;
+}
+
+
+#line 52 "d4_ce_parser.tab.hh" // lalr1.cc:386
+
+# include <cassert>
+# include <vector>
+# include <iostream>
+# include <stdexcept>
+# include <string>
+# include "stack.hh"
+# include "location.hh"
+#include <typeinfo>
+#ifndef YYASSERT
+# include <cassert>
+# define YYASSERT assert
+#endif
+
+
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+
+#line 35 "d4_ce_parser.yy" // lalr1.cc:386
+namespace libdap {
+#line 75 "d4_ce_parser.tab.hh" // lalr1.cc:386
+
+
+
+  /// A char[S] buffer to store and retrieve objects.
+  ///
+  /// Sort of a variant, but does not keep track of the nature
+  /// of the stored data, since that knowledge is available
+  /// via the current state.
+  template <size_t S>
+  struct variant
+  {
+    /// Type of *this.
+    typedef variant<S> self_type;
+
+    /// Empty construction.
+    variant ()
+      : yytname_ (YY_NULL)
+    {}
+
+    /// Construct and fill.
+    template <typename T>
+    variant (const T& t)
+      : yytname_ (typeid (T).name ())
+    {
+      YYASSERT (sizeof (T) <= S);
+      new (yyas_<T> ()) T (t);
+    }
+
+    /// Destruction, allowed only if empty.
+    ~variant ()
+    {
+      YYASSERT (!yytname_);
+    }
+
+    /// Instantiate an empty \a T in here.
+    template <typename T>
+    T&
+    build ()
+    {
+      YYASSERT (!yytname_);
+      YYASSERT (sizeof (T) <= S);
+      yytname_ = typeid (T).name ();
+      return *new (yyas_<T> ()) T;
+    }
+
+    /// Instantiate a \a T in here from \a t.
+    template <typename T>
+    T&
+    build (const T& t)
+    {
+      YYASSERT (!yytname_);
+      YYASSERT (sizeof (T) <= S);
+      yytname_ = typeid (T).name ();
+      return *new (yyas_<T> ()) T (t);
+    }
+
+    /// Accessor to a built \a T.
+    template <typename T>
+    T&
+    as ()
+    {
+      YYASSERT (yytname_ == typeid (T).name ());
+      YYASSERT (sizeof (T) <= S);
+      return *yyas_<T> ();
+    }
+
+    /// Const accessor to a built \a T (for %printer).
+    template <typename T>
+    const T&
+    as () const
+    {
+      YYASSERT (yytname_ == typeid (T).name ());
+      YYASSERT (sizeof (T) <= S);
+      return *yyas_<T> ();
+    }
+
+    /// Swap the content with \a other, of same type.
+    ///
+    /// Both variants must be built beforehand, because swapping the actual
+    /// data requires reading it (with as()), and this is not possible on
+    /// unconstructed variants: it would require some dynamic testing, which
+    /// should not be the variant's responsability.
+    /// Swapping between built and (possibly) non-built is done with
+    /// variant::move ().
+    template <typename T>
+    void
+    swap (self_type& other)
+    {
+      YYASSERT (yytname_);
+      YYASSERT (yytname_ == other.yytname_);
+      std::swap (as<T> (), other.as<T> ());
+    }
+
+    /// Move the content of \a other to this.
+    ///
+    /// Destroys \a other.
+    template <typename T>
+    void
+    move (self_type& other)
+    {
+      YYASSERT (!yytname_);
+      build<T> ();
+      swap<T> (other);
+      other.destroy<T> ();
+    }
+
+    /// Copy the content of \a other to this.
+    template <typename T>
+    void
+    copy (const self_type& other)
+    {
+      build<T> (other.as<T> ());
+    }
+
+    /// Destroy the stored \a T.
+    template <typename T>
+    void
+    destroy ()
+    {
+      as<T> ().~T ();
+      yytname_ = YY_NULL;
+    }
+
+  private:
+    /// Prohibit blind copies.
+    self_type& operator=(const self_type&);
+    variant (const self_type&);
+
+    /// Accessor to raw memory as \a T.
+    template <typename T>
+    T*
+    yyas_ ()
+    {
+      void *yyp = yybuffer_.yyraw;
+      return static_cast<T*> (yyp);
+     }
+
+    /// Const accessor to raw memory as \a T.
+    template <typename T>
+    const T*
+    yyas_ () const
+    {
+      const void *yyp = yybuffer_.yyraw;
+      return static_cast<const T*> (yyp);
+     }
+
+    union
+    {
+      /// Strongest alignment constraints.
+      long double yyalign_me;
+      /// A buffer large enough to store any of the semantic values.
+      char yyraw[S];
+    } yybuffer_;
+
+    /// Whether the content is built: if defined, the name of the stored type.
+    const char *yytname_;
+  };
+
+
+  /// A Bison parser.
+  class D4CEParser
+  {
+  public:
+#ifndef YYSTYPE
+    /// An auxiliary type to compute the largest semantic type.
+    union union_type
+    {
+      // dimensions
+      // dimension
+      // clauses
+      // clause
+      // subset
+      // indexes
+      // fields
+      // filter
+      // predicate
+      char dummy1[sizeof(bool)];
+
+      // index
+      char dummy2[sizeof(libdap::D4ConstraintEvaluator::index)];
+
+      // "word"
+      // "string"
+      // id
+      // group
+      // path
+      // name
+      char dummy3[sizeof(std::string)];
+};
+
+    /// Symbol semantic values.
+    typedef variant<sizeof(union_type)> semantic_type;
+#else
+    typedef YYSTYPE semantic_type;
+#endif
+    /// Symbol locations.
+    typedef location location_type;
+
+    /// Syntax errors thrown from user actions.
+    struct syntax_error : std::runtime_error
+    {
+      syntax_error (const location_type& l, const std::string& m);
+      location_type location;
+    };
+
+    /// Tokens.
+    struct token
+    {
+      enum yytokentype
+      {
+        END = 0,
+        WORD = 258,
+        STRING = 259,
+        SEMICOLON = 260,
+        PIPE = 261,
+        LBRACKET = 262,
+        RBRACKET = 263,
+        COLON = 264,
+        LBRACE = 265,
+        RBRACE = 266,
+        COMMA = 267,
+        ND = 268,
+        ASSIGN = 269,
+        LESS = 270,
+        GREATER = 271,
+        LESS_EQUAL = 272,
+        GREATER_EQUAL = 273,
+        EQUAL = 274,
+        NOT_EQUAL = 275,
+        REGEX_MATCH = 276,
+        LESS_BBOX = 277,
+        GREATER_BBOX = 278,
+        MASK = 279,
+        GROUP_SEP = 280,
+        PATH_SEP = 281
+      };
+    };
+
+    /// (External) token type, as returned by yylex.
+    typedef token::yytokentype token_type;
+
+    /// Internal symbol number.
+    typedef int symbol_number_type;
+
+    /// Internal symbol number for tokens (subsumed by symbol_number_type).
+    typedef unsigned char token_number_type;
+
+    /// A complete symbol.
+    ///
+    /// Expects its Base type to provide access to the symbol type
+    /// via type_get().
+    ///
+    /// Provide access to semantic value and location.
+    template <typename Base>
+    struct basic_symbol : Base
+    {
+      /// Alias to Base.
+      typedef Base super_type;
+
+      /// Default constructor.
+      basic_symbol ();
+
+      /// Copy constructor.
+      basic_symbol (const basic_symbol& other);
+
+      /// Constructor for valueless symbols, and symbols from each type.
+
+  basic_symbol (typename Base::kind_type t, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const bool v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const libdap::D4ConstraintEvaluator::index v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l);
+
+
+      /// Constructor for symbols with semantic value.
+      basic_symbol (typename Base::kind_type t,
+                    const semantic_type& v,
+                    const location_type& l);
+
+      ~basic_symbol ();
+
+      /// Destructive move, \a s is emptied into this.
+      void move (basic_symbol& s);
+
+      /// The semantic value.
+      semantic_type value;
+
+      /// The location.
+      location_type location;
+
+    private:
+      /// Assignment operator.
+      basic_symbol& operator= (const basic_symbol& other);
+    };
+
+    /// Type access provider for token (enum) based symbols.
+    struct by_type
+    {
+      /// Default constructor.
+      by_type ();
+
+      /// Copy constructor.
+      by_type (const by_type& other);
+
+      /// The symbol type as needed by the constructor.
+      typedef token_type kind_type;
+
+      /// Constructor from (external) token numbers.
+      by_type (kind_type t);
+
+      /// Steal the symbol type from \a that.
+      void move (by_type& that);
+
+      /// The (internal) type number (corresponding to \a type).
+      /// -1 when this symbol is empty.
+      symbol_number_type type_get () const;
+
+      /// The token.
+      token_type token () const;
+
+      enum { empty = 0 };
+
+      /// The symbol type.
+      /// -1 when this symbol is empty.
+      token_number_type type;
+    };
+
+    /// "External" symbols: returned by the scanner.
+    typedef basic_symbol<by_type> symbol_type;
+
+    // Symbol constructors declarations.
+    static inline
+    symbol_type
+    make_END (const location_type& l);
+
+    static inline
+    symbol_type
+    make_WORD (const std::string& v, const location_type& l);
+
+    static inline
+    symbol_type
+    make_STRING (const std::string& v, const location_type& l);
+
+    static inline
+    symbol_type
+    make_SEMICOLON (const location_type& l);
+
+    static inline
+    symbol_type
+    make_PIPE (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LBRACKET (const location_type& l);
+
+    static inline
+    symbol_type
+    make_RBRACKET (const location_type& l);
+
+    static inline
+    symbol_type
+    make_COLON (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LBRACE (const location_type& l);
+
+    static inline
+    symbol_type
+    make_RBRACE (const location_type& l);
+
+    static inline
+    symbol_type
+    make_COMMA (const location_type& l);
+
+    static inline
+    symbol_type
+    make_ND (const location_type& l);
+
+    static inline
+    symbol_type
+    make_ASSIGN (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LESS (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GREATER (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LESS_EQUAL (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GREATER_EQUAL (const location_type& l);
+
+    static inline
+    symbol_type
+    make_EQUAL (const location_type& l);
+
+    static inline
+    symbol_type
+    make_NOT_EQUAL (const location_type& l);
+
+    static inline
+    symbol_type
+    make_REGEX_MATCH (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LESS_BBOX (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GREATER_BBOX (const location_type& l);
+
+    static inline
+    symbol_type
+    make_MASK (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GROUP_SEP (const location_type& l);
+
+    static inline
+    symbol_type
+    make_PATH_SEP (const location_type& l);
+
+
+    /// Build a parser object.
+    D4CEParser (D4CEScanner  &scanner_yyarg, D4ConstraintEvaluator  &driver_yyarg);
+    virtual ~D4CEParser ();
+
+    /// Parse.
+    /// \returns  0 iff parsing succeeded.
+    virtual int parse ();
+
+#if YYDEBUG
+    /// The current debugging stream.
+    std::ostream& debug_stream () const;
+    /// Set the current debugging stream.
+    void set_debug_stream (std::ostream &);
+
+    /// Type for debugging levels.
+    typedef int debug_level_type;
+    /// The current debugging level.
+    debug_level_type debug_level () const;
+    /// Set the current debugging level.
+    void set_debug_level (debug_level_type l);
+#endif
+
+    /// Report a syntax error.
+    /// \param loc    where the syntax error is found.
+    /// \param msg    a description of the syntax error.
+    virtual void error (const location_type& loc, const std::string& msg);
+
+    /// Report a syntax error.
+    void error (const syntax_error& err);
+
+  private:
+    /// This class is not copyable.
+    D4CEParser (const D4CEParser&);
+    D4CEParser& operator= (const D4CEParser&);
+
+    /// State numbers.
+    typedef int state_type;
+
+    /// Generate an error message.
+    /// \param yystate   the state where the error occurred.
+    /// \param yytoken   the lookahead token type, or yyempty_.
+    virtual std::string yysyntax_error_ (state_type yystate,
+                                         symbol_number_type yytoken) const;
+
+    /// Compute post-reduction state.
+    /// \param yystate   the current state
+    /// \param yylhs     the nonterminal to push on the stack
+    state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
+
+    /// Whether the given \c yypact_ value indicates a defaulted state.
+    /// \param yyvalue   the value to check
+    static bool yy_pact_value_is_default_ (int yyvalue);
+
+    /// Whether the given \c yytable_ value indicates a syntax error.
+    /// \param yyvalue   the value to check
+    static bool yy_table_value_is_error_ (int yyvalue);
+
+    static const signed char yypact_ninf_;
+    static const signed char yytable_ninf_;
+
+    /// Convert a scanner token number \a t to a symbol number.
+    static token_number_type yytranslate_ (int t);
+
+    // Tables.
+  // YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+  // STATE-NUM.
+  static const signed char yypact_[];
+
+  // YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+  // Performed when YYTABLE does not specify something else to do.  Zero
+  // means the default is an error.
+  static const unsigned char yydefact_[];
+
+  // YYPGOTO[NTERM-NUM].
+  static const signed char yypgoto_[];
+
+  // YYDEFGOTO[NTERM-NUM].
+  static const signed char yydefgoto_[];
+
+  // YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+  // positive, shift that token.  If negative, reduce the rule whose
+  // number is the opposite.  If YYTABLE_NINF, syntax error.
+  static const signed char yytable_[];
+
+  static const signed char yycheck_[];
+
+  // YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+  // symbol of state STATE-NUM.
+  static const unsigned char yystos_[];
+
+  // YYR1[YYN] -- Symbol number of symbol that rule YYN derives.
+  static const unsigned char yyr1_[];
+
+  // YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.
+  static const unsigned char yyr2_[];
+
+
+    /// Convert the symbol name \a n to a form suitable for a diagnostic.
+    static std::string yytnamerr_ (const char *n);
+
+
+    /// For a symbol, its name in clear.
+    static const char* const yytname_[];
+#if YYDEBUG
+  // YYRLINE[YYN] -- Source line where rule number YYN was defined.
+  static const unsigned short int yyrline_[];
+    /// Report on the debug stream that the rule \a r is going to be reduced.
+    virtual void yy_reduce_print_ (int r);
+    /// Print the state stack on the debug stream.
+    virtual void yystack_print_ ();
+
+    // Debugging.
+    int yydebug_;
+    std::ostream* yycdebug_;
+
+    /// \brief Display a symbol type, value and location.
+    /// \param yyo    The output stream.
+    /// \param yysym  The symbol.
+    template <typename Base>
+    void yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const;
+#endif
+
+    /// \brief Reclaim the memory associated to a symbol.
+    /// \param yymsg     Why this token is reclaimed.
+    ///                  If null, print nothing.
+    /// \param s         The symbol.
+    template <typename Base>
+    void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
+
+  private:
+    /// Type access provider for state based symbols.
+    struct by_state
+    {
+      /// Default constructor.
+      by_state ();
+
+      /// The symbol type as needed by the constructor.
+      typedef state_type kind_type;
+
+      /// Constructor.
+      by_state (kind_type s);
+
+      /// Copy constructor.
+      by_state (const by_state& other);
+
+      /// Steal the symbol type from \a that.
+      void move (by_state& that);
+
+      /// The (internal) type number (corresponding to \a state).
+      /// "empty" when empty.
+      symbol_number_type type_get () const;
+
+      enum { empty = 0 };
+
+      /// The state.
+      state_type state;
+    };
+
+    /// "Internal" symbol: element of the stack.
+    struct stack_symbol_type : basic_symbol<by_state>
+    {
+      /// Superclass.
+      typedef basic_symbol<by_state> super_type;
+      /// Construct an empty symbol.
+      stack_symbol_type ();
+      /// Steal the contents from \a sym to build this.
+      stack_symbol_type (state_type s, symbol_type& sym);
+      /// Assignment, needed by push_back.
+      stack_symbol_type& operator= (const stack_symbol_type& that);
+    };
+
+    /// Stack type.
+    typedef stack<stack_symbol_type> stack_type;
+
+    /// The stack.
+    stack_type yystack_;
+
+    /// Push a new state on the stack.
+    /// \param m    a debug message to display
+    ///             if null, no trace is output.
+    /// \param s    the symbol
+    /// \warning the contents of \a s.value is stolen.
+    void yypush_ (const char* m, stack_symbol_type& s);
+
+    /// Push a new look ahead token on the state on the stack.
+    /// \param m    a debug message to display
+    ///             if null, no trace is output.
+    /// \param s    the state
+    /// \param sym  the symbol (for its value and location).
+    /// \warning the contents of \a s.value is stolen.
+    void yypush_ (const char* m, state_type s, symbol_type& sym);
+
+    /// Pop \a n symbols the three stacks.
+    void yypop_ (unsigned int n = 1);
+
+    // Constants.
+    enum
+    {
+      yyeof_ = 0,
+      yylast_ = 69,           //< Last index in yytable_.
+      yynnts_ = 20,  //< Number of nonterminal symbols.
+      yyempty_ = -2,
+      yyfinal_ = 16, //< Termination state number.
+      yyterror_ = 1,
+      yyerrcode_ = 256,
+      yyntokens_ = 27    //< Number of tokens.
+    };
+
+
+    // User arguments.
+    D4CEScanner  &scanner;
+    D4ConstraintEvaluator  &driver;
+  };
+
+
+#line 35 "d4_ce_parser.yy" // lalr1.cc:386
+} // libdap
+#line 727 "d4_ce_parser.tab.hh" // lalr1.cc:386
+
+
+
+
+#endif // !YY_YY_D4_CE_PARSER_TAB_HH_INCLUDED
diff --git a/d4_ce/gen_grammar_sources/d4_function_parser.tab.cc.tmp b/d4_ce/gen_grammar_sources/d4_function_parser.tab.cc.tmp
new file mode 100644
index 0000000..c1b91cd
--- /dev/null
+++ b/d4_ce/gen_grammar_sources/d4_function_parser.tab.cc.tmp
@@ -0,0 +1,2467 @@
+// A Bison parser, made by GNU Bison 3.0.
+
+// Skeleton implementation for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+
+// First part of user declarations.
+
+#line 37 "d4_function_parser.tab.cc" // lalr1.cc:398
+
+# ifndef YY_NULL
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULL nullptr
+#  else
+#   define YY_NULL 0
+#  endif
+# endif
+
+#include "d4_function_parser.tab.hh"
+
+// User implementation prologue.
+
+#line 51 "d4_function_parser.tab.cc" // lalr1.cc:406
+// Unqualified %code blocks.
+#line 77 "d4_function_parser.yy" // lalr1.cc:407
+
+    #include "BaseType.h"
+    #include "DMR.h"
+    #include "D4RValue.h"
+    #include "ServerFunctionsList.h"
+   
+    #include "parser-util.h"
+
+    /* include for all driver functions */
+    #include "D4FunctionEvaluator.h"
+
+    using namespace libdap ;
+    
+    /* this is silly, but I can't figure out a way around it */
+    static int yylex(libdap::D4FunctionParser::semantic_type *yylval,
+                     libdap::location *loc,
+                     libdap::D4FunctionScanner  &scanner,
+                     libdap::D4FunctionEvaluator   &evaluator);
+
+#line 73 "d4_function_parser.tab.cc" // lalr1.cc:407
+
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> // FIXME: INFRINGES ON USER NAME SPACE.
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
+/* 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).  */
+
+# ifndef YYLLOC_DEFAULT
+#  define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                  \
+      if (N)                                                            \
+        {                                                               \
+          (Current).begin  = YYRHSLOC (Rhs, 1).begin;                   \
+          (Current).end    = YYRHSLOC (Rhs, N).end;                     \
+        }                                                               \
+      else                                                              \
+        {                                                               \
+          (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end;      \
+        }                                                               \
+    while (/*CONSTCOND*/ false)
+# endif
+
+
+// Suppress unused-variable warnings by "using" E.
+#define YYUSE(E) ((void) (E))
+
+// Enable debugging if requested.
+#if YYDEBUG
+
+// A pseudo ostream that takes yydebug_ into account.
+# define YYCDEBUG if (yydebug_) (*yycdebug_)
+
+# define YY_SYMBOL_PRINT(Title, Symbol)         \
+  do {                                          \
+    if (yydebug_)                               \
+    {                                           \
+      *yycdebug_ << Title << ' ';               \
+      yy_print_ (*yycdebug_, Symbol);           \
+      *yycdebug_ << std::endl;                  \
+    }                                           \
+  } while (false)
+
+# define YY_REDUCE_PRINT(Rule)          \
+  do {                                  \
+    if (yydebug_)                       \
+      yy_reduce_print_ (Rule);          \
+  } while (false)
+
+# define YY_STACK_PRINT()               \
+  do {                                  \
+    if (yydebug_)                       \
+      yystack_print_ ();                \
+  } while (false)
+
+#else // !YYDEBUG
+
+# define YYCDEBUG if (false) std::cerr
+# define YY_SYMBOL_PRINT(Title, Symbol)  YYUSE(Symbol)
+# define YY_REDUCE_PRINT(Rule)           static_cast<void>(0)
+# define YY_STACK_PRINT()                static_cast<void>(0)
+
+#endif // !YYDEBUG
+
+#define yyerrok         (yyerrstatus_ = 0)
+#define yyclearin       (yyempty = true)
+
+#define YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
+#define YYRECOVERING()  (!!yyerrstatus_)
+
+#line 34 "d4_function_parser.yy" // lalr1.cc:473
+namespace libdap {
+#line 159 "d4_function_parser.tab.cc" // lalr1.cc:473
+
+  /* Return 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.  */
+  std::string
+  D4FunctionParser::yytnamerr_ (const char *yystr)
+  {
+    if (*yystr == '"')
+      {
+        std::string yyr = "";
+        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:
+              yyr += *yyp;
+              break;
+
+            case '"':
+              return yyr;
+            }
+      do_not_strip_quotes: ;
+      }
+
+    return yystr;
+  }
+
+
+  /// Build a parser object.
+  D4FunctionParser::D4FunctionParser (D4FunctionScanner  &scanner_yyarg, D4FunctionEvaluator  &evaluator_yyarg)
+    :
+#if YYDEBUG
+      yydebug_ (false),
+      yycdebug_ (&std::cerr),
+#endif
+      scanner (scanner_yyarg),
+      evaluator (evaluator_yyarg)
+  {}
+
+  D4FunctionParser::~D4FunctionParser ()
+  {}
+
+
+  /*---------------.
+  | Symbol types.  |
+  `---------------*/
+
+  inline
+  D4FunctionParser::syntax_error::syntax_error (const location_type& l, const std::string& m)
+    : std::runtime_error (m)
+    , location (l)
+  {}
+
+  // basic_symbol.
+  template <typename Base>
+  inline
+  D4FunctionParser::basic_symbol<Base>::basic_symbol ()
+    : value ()
+  {}
+
+  template <typename Base>
+  inline
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
+    : Base (other)
+    , value ()
+    , location (other.location)
+  {
+      switch (other.type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.copy< D4Function > (other.value);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.copy< D4RValue* > (other.value);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.copy< D4RValueList* > (other.value);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.copy< std::string > (other.value);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.copy< std::vector<dods_byte>* > (other.value);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.copy< std::vector<dods_float32>* > (other.value);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.copy< std::vector<dods_float64>* > (other.value);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.copy< std::vector<dods_int16>* > (other.value);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.copy< std::vector<dods_int32>* > (other.value);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.copy< std::vector<dods_int64>* > (other.value);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.copy< std::vector<dods_int8>* > (other.value);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.copy< std::vector<dods_uint16>* > (other.value);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.copy< std::vector<dods_uint32>* > (other.value);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.copy< std::vector<dods_uint64>* > (other.value);
+        break;
+
+      default:
+        break;
+    }
+
+  }
+
+
+  template <typename Base>
+  inline
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const semantic_type& v, const location_type& l)
+    : Base (t)
+    , value ()
+    , location (l)
+  {
+    (void) v;
+      switch (this->type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.copy< D4Function > (v);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.copy< D4RValue* > (v);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.copy< D4RValueList* > (v);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.copy< std::string > (v);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.copy< std::vector<dods_byte>* > (v);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.copy< std::vector<dods_float32>* > (v);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.copy< std::vector<dods_float64>* > (v);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.copy< std::vector<dods_int16>* > (v);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.copy< std::vector<dods_int32>* > (v);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.copy< std::vector<dods_int64>* > (v);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.copy< std::vector<dods_int8>* > (v);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.copy< std::vector<dods_uint16>* > (v);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.copy< std::vector<dods_uint32>* > (v);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.copy< std::vector<dods_uint64>* > (v);
+        break;
+
+      default:
+        break;
+    }
+}
+
+
+  // Implementation of basic_symbol constructor for each type.
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const location_type& l)
+    : Base (t)
+    , value ()
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const D4Function v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const D4RValue* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const D4RValueList* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_byte>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_float32>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_float64>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_int16>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_int32>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_int64>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_int8>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_uint16>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_uint32>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+  template <typename Base>
+  D4FunctionParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const std::vector<dods_uint64>* v, const location_type& l)
+    : Base (t)
+    , value (v)
+    , location (l)
+  {}
+
+
+  template <typename Base>
+  inline
+  D4FunctionParser::basic_symbol<Base>::~basic_symbol ()
+  {
+    // User destructor.
+    symbol_number_type yytype = this->type_get ();
+    switch (yytype)
+    {
+   default:
+      break;
+    }
+
+    // Type destructor.
+    switch (yytype)
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.template destroy< D4Function > ();
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.template destroy< D4RValue* > ();
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.template destroy< D4RValueList* > ();
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.template destroy< std::string > ();
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.template destroy< std::vector<dods_byte>* > ();
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.template destroy< std::vector<dods_float32>* > ();
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.template destroy< std::vector<dods_float64>* > ();
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.template destroy< std::vector<dods_int16>* > ();
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.template destroy< std::vector<dods_int32>* > ();
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.template destroy< std::vector<dods_int64>* > ();
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.template destroy< std::vector<dods_int8>* > ();
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.template destroy< std::vector<dods_uint16>* > ();
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.template destroy< std::vector<dods_uint32>* > ();
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.template destroy< std::vector<dods_uint64>* > ();
+        break;
+
+      default:
+        break;
+    }
+
+  }
+
+  template <typename Base>
+  inline
+  void
+  D4FunctionParser::basic_symbol<Base>::move (basic_symbol& s)
+  {
+    super_type::move(s);
+      switch (this->type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.move< D4Function > (s.value);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.move< D4RValue* > (s.value);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.move< D4RValueList* > (s.value);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.move< std::string > (s.value);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.move< std::vector<dods_byte>* > (s.value);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.move< std::vector<dods_float32>* > (s.value);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.move< std::vector<dods_float64>* > (s.value);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.move< std::vector<dods_int16>* > (s.value);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.move< std::vector<dods_int32>* > (s.value);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.move< std::vector<dods_int64>* > (s.value);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.move< std::vector<dods_int8>* > (s.value);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.move< std::vector<dods_uint16>* > (s.value);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.move< std::vector<dods_uint32>* > (s.value);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.move< std::vector<dods_uint64>* > (s.value);
+        break;
+
+      default:
+        break;
+    }
+
+    location = s.location;
+  }
+
+  // by_type.
+  inline
+  D4FunctionParser::by_type::by_type ()
+     : type (empty)
+  {}
+
+  inline
+  D4FunctionParser::by_type::by_type (const by_type& other)
+    : type (other.type)
+  {}
+
+  inline
+  D4FunctionParser::by_type::by_type (token_type t)
+    : type (yytranslate_ (t))
+  {}
+
+  inline
+  void
+  D4FunctionParser::by_type::move (by_type& that)
+  {
+    type = that.type;
+    that.type = empty;
+  }
+
+  inline
+  int
+  D4FunctionParser::by_type::type_get () const
+  {
+    return type;
+  }
+  // Implementation of make_symbol for each symbol type.
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_END (const location_type& l)
+  {
+    return symbol_type (token::END, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_WORD (const std::string& v, const location_type& l)
+  {
+    return symbol_type (token::WORD, v, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_STRING (const std::string& v, const location_type& l)
+  {
+    return symbol_type (token::STRING, v, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_SEMICOLON (const location_type& l)
+  {
+    return symbol_type (token::SEMICOLON, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_COLON (const location_type& l)
+  {
+    return symbol_type (token::COLON, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_LPAREN (const location_type& l)
+  {
+    return symbol_type (token::LPAREN, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_RPAREN (const location_type& l)
+  {
+    return symbol_type (token::RPAREN, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_COMMA (const location_type& l)
+  {
+    return symbol_type (token::COMMA, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_GROUP_SEP (const location_type& l)
+  {
+    return symbol_type (token::GROUP_SEP, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_PATH_SEP (const location_type& l)
+  {
+    return symbol_type (token::PATH_SEP, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_BYTE (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_BYTE, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_UINT8 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_UINT8, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_INT8 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_INT8, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_UINT16 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_UINT16, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_INT16 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_INT16, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_UINT32 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_UINT32, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_INT32 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_INT32, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_UINT64 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_UINT64, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_INT64 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_INT64, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_FLOAT32 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_FLOAT32, l);
+
+  }
+
+  D4FunctionParser::symbol_type
+  D4FunctionParser::make_DOLLAR_FLOAT64 (const location_type& l)
+  {
+    return symbol_type (token::DOLLAR_FLOAT64, l);
+
+  }
+
+
+
+  // by_state.
+  inline
+  D4FunctionParser::by_state::by_state ()
+    : state (empty)
+  {}
+
+  inline
+  D4FunctionParser::by_state::by_state (const by_state& other)
+    : state (other.state)
+  {}
+
+  inline
+  void
+  D4FunctionParser::by_state::move (by_state& that)
+  {
+    state = that.state;
+    that.state = empty;
+  }
+
+  inline
+  D4FunctionParser::by_state::by_state (state_type s)
+    : state (s)
+  {}
+
+  inline
+  D4FunctionParser::symbol_number_type
+  D4FunctionParser::by_state::type_get () const
+  {
+    return state == empty ? 0 : yystos_[state];
+  }
+
+  inline
+  D4FunctionParser::stack_symbol_type::stack_symbol_type ()
+  {}
+
+
+  inline
+  D4FunctionParser::stack_symbol_type::stack_symbol_type (state_type s, symbol_type& that)
+    : super_type (s, that.location)
+  {
+      switch (that.type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.move< D4Function > (that.value);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.move< D4RValue* > (that.value);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.move< D4RValueList* > (that.value);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.move< std::string > (that.value);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.move< std::vector<dods_byte>* > (that.value);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.move< std::vector<dods_float32>* > (that.value);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.move< std::vector<dods_float64>* > (that.value);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.move< std::vector<dods_int16>* > (that.value);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.move< std::vector<dods_int32>* > (that.value);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.move< std::vector<dods_int64>* > (that.value);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.move< std::vector<dods_int8>* > (that.value);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.move< std::vector<dods_uint16>* > (that.value);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.move< std::vector<dods_uint32>* > (that.value);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.move< std::vector<dods_uint64>* > (that.value);
+        break;
+
+      default:
+        break;
+    }
+
+    // that is emptied.
+    that.type = empty;
+  }
+
+  inline
+  D4FunctionParser::stack_symbol_type&
+  D4FunctionParser::stack_symbol_type::operator= (const stack_symbol_type& that)
+  {
+    state = that.state;
+      switch (that.type_get ())
+    {
+      case 7: // "function name"
+      case 44: // fname
+        value.copy< D4Function > (that.value);
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        value.copy< D4RValue* > (that.value);
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        value.copy< D4RValueList* > (that.value);
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        value.copy< std::string > (that.value);
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        value.copy< std::vector<dods_byte>* > (that.value);
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        value.copy< std::vector<dods_float32>* > (that.value);
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        value.copy< std::vector<dods_float64>* > (that.value);
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        value.copy< std::vector<dods_int16>* > (that.value);
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        value.copy< std::vector<dods_int32>* > (that.value);
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        value.copy< std::vector<dods_int64>* > (that.value);
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        value.copy< std::vector<dods_int8>* > (that.value);
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        value.copy< std::vector<dods_uint16>* > (that.value);
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        value.copy< std::vector<dods_uint32>* > (that.value);
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        value.copy< std::vector<dods_uint64>* > (that.value);
+        break;
+
+      default:
+        break;
+    }
+
+    location = that.location;
+    return *this;
+  }
+
+
+  template <typename Base>
+  inline
+  void
+  D4FunctionParser::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
+  {
+    if (yymsg)
+      YY_SYMBOL_PRINT (yymsg, yysym);
+  }
+
+#if YYDEBUG
+  template <typename Base>
+  void
+  D4FunctionParser::yy_print_ (std::ostream& yyo,
+                                     const basic_symbol<Base>& yysym) const
+  {
+    std::ostream& yyoutput = yyo;
+    YYUSE (yyoutput);
+    symbol_number_type yytype = yysym.type_get ();
+    yyo << (yytype < yyntokens_ ? "token" : "nterm")
+        << ' ' << yytname_[yytype] << " ("
+        << yysym.location << ": ";
+    YYUSE (yytype);
+    yyo << ')';
+  }
+#endif
+
+  inline
+  void
+  D4FunctionParser::yypush_ (const char* m, state_type s, symbol_type& sym)
+  {
+    stack_symbol_type t (s, sym);
+    yypush_ (m, t);
+  }
+
+  inline
+  void
+  D4FunctionParser::yypush_ (const char* m, stack_symbol_type& s)
+  {
+    if (m)
+      YY_SYMBOL_PRINT (m, s);
+    yystack_.push (s);
+  }
+
+  inline
+  void
+  D4FunctionParser::yypop_ (unsigned int n)
+  {
+    yystack_.pop (n);
+  }
+
+#if YYDEBUG
+  std::ostream&
+  D4FunctionParser::debug_stream () const
+  {
+    return *yycdebug_;
+  }
+
+  void
+  D4FunctionParser::set_debug_stream (std::ostream& o)
+  {
+    yycdebug_ = &o;
+  }
+
+
+  D4FunctionParser::debug_level_type
+  D4FunctionParser::debug_level () const
+  {
+    return yydebug_;
+  }
+
+  void
+  D4FunctionParser::set_debug_level (debug_level_type l)
+  {
+    yydebug_ = l;
+  }
+#endif // YYDEBUG
+
+  inline D4FunctionParser::state_type
+  D4FunctionParser::yy_lr_goto_state_ (state_type yystate, int yylhs)
+  {
+    int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
+    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+      return yytable_[yyr];
+    else
+      return yydefgoto_[yylhs - yyntokens_];
+  }
+
+  inline bool
+  D4FunctionParser::yy_pact_value_is_default_ (int yyvalue)
+  {
+    return yyvalue == yypact_ninf_;
+  }
+
+  inline bool
+  D4FunctionParser::yy_table_value_is_error_ (int yyvalue)
+  {
+    return yyvalue == yytable_ninf_;
+  }
+
+  int
+  D4FunctionParser::parse ()
+  {
+    /// Whether yyla contains a lookahead.
+    bool yyempty = true;
+
+    // State.
+    int yyn;
+    int yylen = 0;
+
+    // Error handling.
+    int yynerrs_ = 0;
+    int yyerrstatus_ = 0;
+
+    /// The lookahead symbol.
+    symbol_type yyla;
+
+    /// The locations where the error started and ended.
+    stack_symbol_type yyerror_range[3];
+
+    /// $$ and @$.
+    stack_symbol_type yylhs;
+
+    /// The return value of parse ().
+    int yyresult;
+
+    // FIXME: This shoud be completely indented.  It is not yet to
+    // avoid gratuitous conflicts when merging into the master branch.
+    try
+      {
+    YYCDEBUG << "Starting parse" << std::endl;
+
+
+    // User initialization code.
+    #line 69 "d4_function_parser.yy" // lalr1.cc:730
+{
+    // Initialize the initial location. This is printed when the parser builds
+    // its own error messages - when the parse fails as opposed to when the 
+    // function(s) name(s) a missing variable, ...
+
+    yyla.location.initialize (evaluator.expression());
+}
+
+#line 1287 "d4_function_parser.tab.cc" // lalr1.cc:730
+
+    /* Initialize the stack.  The initial state will be set in
+       yynewstate, since the latter expects the semantical and the
+       location values to have been already stored, initialize these
+       stacks with a primary value.  */
+    yystack_.clear ();
+    yypush_ (YY_NULL, 0, yyla);
+
+    // A new symbol was pushed on the stack.
+  yynewstate:
+    YYCDEBUG << "Entering state " << yystack_[0].state << std::endl;
+
+    // Accept?
+    if (yystack_[0].state == yyfinal_)
+      goto yyacceptlab;
+
+    goto yybackup;
+
+    // Backup.
+  yybackup:
+
+    // Try to take a decision without lookahead.
+    yyn = yypact_[yystack_[0].state];
+    if (yy_pact_value_is_default_ (yyn))
+      goto yydefault;
+
+    // Read a lookahead token.
+    if (yyempty)
+      {
+        YYCDEBUG << "Reading a token: ";
+        try
+          {
+            yyla.type = yytranslate_ (yylex (&yyla.value, &yyla.location, scanner, evaluator));
+          }
+        catch (const syntax_error& yyexc)
+          {
+            error (yyexc);
+            goto yyerrlab1;
+          }
+        yyempty = false;
+      }
+    YY_SYMBOL_PRINT ("Next token is", yyla);
+
+    /* If the proper action on seeing token YYLA.TYPE is to reduce or
+       to detect an error, take that action.  */
+    yyn += yyla.type_get ();
+    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
+      goto yydefault;
+
+    // Reduce or error.
+    yyn = yytable_[yyn];
+    if (yyn <= 0)
+      {
+        if (yy_table_value_is_error_ (yyn))
+          goto yyerrlab;
+        yyn = -yyn;
+        goto yyreduce;
+      }
+
+    // Discard the token being shifted.
+    yyempty = true;
+
+    // Count tokens shifted since error; after three, turn off error status.
+    if (yyerrstatus_)
+      --yyerrstatus_;
+
+    // Shift the lookahead token.
+    yypush_ ("Shifting", yyn, yyla);
+    goto yynewstate;
+
+  /*-----------------------------------------------------------.
+  | yydefault -- do the default action for the current state.  |
+  `-----------------------------------------------------------*/
+  yydefault:
+    yyn = yydefact_[yystack_[0].state];
+    if (yyn == 0)
+      goto yyerrlab;
+    goto yyreduce;
+
+  /*-----------------------------.
+  | yyreduce -- Do a reduction.  |
+  `-----------------------------*/
+  yyreduce:
+    yylen = yyr2_[yyn];
+    yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);
+    /* Variants are always initialized to an empty instance of the
+       correct type. The default $$=$1 action is NOT applied when using
+       variants.  */
+      switch (yyr1_[yyn])
+    {
+      case 7: // "function name"
+      case 44: // fname
+        yylhs.value.build< D4Function > ();
+        break;
+
+      case 5: // "argument"
+      case 6: // "function"
+      case 8: // "variable or constant"
+      case 9: // "array constant"
+      case 43: // function
+      case 46: // arg
+      case 47: // variable_or_constant
+      case 48: // array_constant
+        yylhs.value.build< D4RValue* > ();
+        break;
+
+      case 3: // "functions"
+      case 4: // "arguments"
+      case 42: // functions
+      case 45: // args
+        yylhs.value.build< D4RValueList* > ();
+        break;
+
+      case 20: // "word"
+      case 21: // "string"
+      case 60: // id
+      case 61: // group
+      case 62: // path
+      case 63: // name
+        yylhs.value.build< std::string > ();
+        break;
+
+      case 10: // "fast byte arg list"
+      case 50: // fast_byte_arg_list
+        yylhs.value.build< std::vector<dods_byte>* > ();
+        break;
+
+      case 18: // "fast float32 arg list"
+      case 58: // fast_float32_arg_list
+        yylhs.value.build< std::vector<dods_float32>* > ();
+        break;
+
+      case 19: // "fast float64 arg list"
+      case 59: // fast_float64_arg_list
+        yylhs.value.build< std::vector<dods_float64>* > ();
+        break;
+
+      case 13: // "fast int16 arg list"
+      case 53: // fast_int16_arg_list
+        yylhs.value.build< std::vector<dods_int16>* > ();
+        break;
+
+      case 15: // "fast int32 arg list"
+      case 55: // fast_int32_arg_list
+        yylhs.value.build< std::vector<dods_int32>* > ();
+        break;
+
+      case 17: // "fast int64 arg list"
+      case 57: // fast_int64_arg_list
+        yylhs.value.build< std::vector<dods_int64>* > ();
+        break;
+
+      case 11: // "fast int8 arg list"
+      case 51: // fast_int8_arg_list
+        yylhs.value.build< std::vector<dods_int8>* > ();
+        break;
+
+      case 12: // "fast uint16 arg list"
+      case 52: // fast_uint16_arg_list
+        yylhs.value.build< std::vector<dods_uint16>* > ();
+        break;
+
+      case 14: // "fast uint32 arg list"
+      case 54: // fast_uint32_arg_list
+        yylhs.value.build< std::vector<dods_uint32>* > ();
+        break;
+
+      case 16: // "fast uint64 arg list"
+      case 56: // fast_uint64_arg_list
+        yylhs.value.build< std::vector<dods_uint64>* > ();
+        break;
+
+      default:
+        break;
+    }
+
+
+    // Compute the default @$.
+    {
+      slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
+      YYLLOC_DEFAULT (yylhs.location, slice, yylen);
+    }
+
+    // Perform the reduction.
+    YY_REDUCE_PRINT (yyn);
+    try
+      {
+        switch (yyn)
+          {
+  case 2:
+#line 156 "d4_function_parser.yy" // lalr1.cc:846
+    { 
+    evaluator.set_result(yystack_[0].value.as< D4RValueList* > ()); 
+}
+#line 1482 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 3:
+#line 162 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValueList* > () = new D4RValueList(yystack_[0].value.as< D4RValue* > ()); 
+}
+#line 1490 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 4:
+#line 166 "d4_function_parser.yy" // lalr1.cc:846
+    { 
+    yystack_[2].value.as< D4RValueList* > ()->add_rvalue(yystack_[0].value.as< D4RValue* > ());
+    yylhs.value.as< D4RValueList* > () = yystack_[2].value.as< D4RValueList* > (); 
+}
+#line 1499 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 5:
+#line 173 "d4_function_parser.yy" // lalr1.cc:846
+    { 
+    yylhs.value.as< D4RValue* > () = new D4RValue(yystack_[3].value.as< D4Function > (), yystack_[1].value.as< D4RValueList* > ()); // Build a D4RValue from a D4Function pointer and a D4RValueList 
+}
+#line 1507 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 6:
+#line 179 "d4_function_parser.yy" // lalr1.cc:846
+    { 
+    D4Function f;
+    if (!evaluator.sf_list()->find_function(yystack_[0].value.as< std::string > (), &f)) {
+        // ...cloud use @1.{first,last}_column in these error messages.
+        throw Error("'" + yystack_[0].value.as< std::string > () + "' is not a registered DAP4 server function.");
+    }
+
+    yylhs.value.as< D4Function > () = f;
+}
+#line 1521 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 7:
+#line 191 "d4_function_parser.yy" // lalr1.cc:846
+    { 
+    yylhs.value.as< D4RValueList* > () = new D4RValueList(yystack_[0].value.as< D4RValue* > ()); // build a D4RValueList from the D4RValue
+}
+#line 1529 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 8:
+#line 195 "d4_function_parser.yy" // lalr1.cc:846
+    { 
+    yystack_[2].value.as< D4RValueList* > ()->add_rvalue(yystack_[0].value.as< D4RValue* > ());
+    yylhs.value.as< D4RValueList* > () = yystack_[2].value.as< D4RValueList* > (); // Append the D4RValue ($3) to the D4RValueList ($1), then return
+}
+#line 1538 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 9:
+#line 202 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = yystack_[0].value.as< D4RValue* > ();
+}
+#line 1546 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 10:
+#line 206 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = yystack_[0].value.as< D4RValue* > ();
+}
+#line 1554 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 11:
+#line 210 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = yystack_[0].value.as< D4RValue* > ();
+}
+#line 1562 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 12:
+#line 216 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    D4RValue *rvalue = evaluator.build_rvalue(yystack_[0].value.as< std::string > ());
+    if (!rvalue) {
+        throw Error("'" + yystack_[0].value.as< std::string > () + "' is not a variable, number or string.");
+    }
+    
+    yylhs.value.as< D4RValue* > () = rvalue;
+}
+#line 1575 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 13:
+#line 228 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_byte>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_byte>* > ();
+}
+#line 1584 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 14:
+#line 234 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_byte>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_byte>* > ();
+}
+#line 1593 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 15:
+#line 240 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_int8>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_int8>* > ();
+}
+#line 1602 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 16:
+#line 246 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_uint16>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_uint16>* > ();
+}
+#line 1611 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 17:
+#line 252 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_int16>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_int16>* > ();
+}
+#line 1620 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 18:
+#line 258 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_uint32>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_uint32>* > ();
+}
+#line 1629 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 19:
+#line 264 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_int32>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_int32>* > ();
+}
+#line 1638 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 20:
+#line 270 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_uint64>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_uint64>* > ();
+}
+#line 1647 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 21:
+#line 276 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_int64>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_int64>* > ();
+}
+#line 1656 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 22:
+#line 282 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_float32>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_float32>* > ();
+}
+#line 1665 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 23:
+#line 288 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< D4RValue* > () = new D4RValue(*(yystack_[1].value.as< std::vector<dods_float64>* > ()));
+    delete yystack_[1].value.as< std::vector<dods_float64>* > ();
+}
+#line 1674 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 24:
+#line 300 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    evaluator.set_arg_length_hint(get_ull(yystack_[0].value.as< std::string > ().c_str()));
+}
+#line 1682 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 25:
+#line 306 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_byte>* > () = evaluator.init_arg_list(dods_byte(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1690 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 26:
+#line 310 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_byte>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_byte>* > () = yystack_[2].value.as< std::vector<dods_byte>* > ();
+}
+#line 1699 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 27:
+#line 317 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_int8>* > () = evaluator.init_arg_list(dods_int8(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1707 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 28:
+#line 321 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_int8>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_int8>* > () = yystack_[2].value.as< std::vector<dods_int8>* > ();
+}
+#line 1716 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 29:
+#line 328 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_uint16>* > () = evaluator.init_arg_list(dods_uint16(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1724 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 30:
+#line 332 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_uint16>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_uint16>* > () = yystack_[2].value.as< std::vector<dods_uint16>* > ();
+}
+#line 1733 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 31:
+#line 339 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_int16>* > () = evaluator.init_arg_list(dods_int16(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1741 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 32:
+#line 343 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_int16>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_int16>* > () = yystack_[2].value.as< std::vector<dods_int16>* > ();
+}
+#line 1750 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 33:
+#line 350 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_uint32>* > () = evaluator.init_arg_list(dods_uint32(strtoul(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1758 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 34:
+#line 354 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_uint32>* > ()->push_back(strtoul(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_uint32>* > () = yystack_[2].value.as< std::vector<dods_uint32>* > ();
+}
+#line 1767 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 35:
+#line 360 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_int32>* > () = evaluator.init_arg_list(dods_int32(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1775 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 36:
+#line 364 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_int32>* > ()->push_back(strtol(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_int32>* > () = yystack_[2].value.as< std::vector<dods_int32>* > ();
+}
+#line 1784 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 37:
+#line 371 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_uint64>* > () = evaluator.init_arg_list(dods_uint64(strtoull(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1792 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 38:
+#line 375 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_uint64>* > ()->push_back(strtoull(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_uint64>* > () = yystack_[2].value.as< std::vector<dods_uint64>* > ();
+}
+#line 1801 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 39:
+#line 382 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_int64>* > () = evaluator.init_arg_list(dods_int64(strtoll(yystack_[0].value.as< std::string > ().c_str(), 0, 0)));
+}
+#line 1809 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 40:
+#line 386 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_int64>* > ()->push_back(strtoll(yystack_[0].value.as< std::string > ().c_str(), 0, 0));
+    yylhs.value.as< std::vector<dods_int64>* > () = yystack_[2].value.as< std::vector<dods_int64>* > ();
+}
+#line 1818 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 41:
+#line 396 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_float32>* > () = evaluator.init_arg_list(dods_float32(strtof(yystack_[0].value.as< std::string > ().c_str(), 0)));
+}
+#line 1826 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 42:
+#line 400 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_float32>* > ()->push_back(strtof(yystack_[0].value.as< std::string > ().c_str(), 0));
+    yylhs.value.as< std::vector<dods_float32>* > () = yystack_[2].value.as< std::vector<dods_float32>* > ();
+}
+#line 1835 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 43:
+#line 407 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::vector<dods_float64>* > () = evaluator.init_arg_list(dods_float64(strtod(yystack_[0].value.as< std::string > ().c_str(), 0)));
+}
+#line 1843 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 44:
+#line 411 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::vector<dods_float64>* > ()->push_back(strtod(yystack_[0].value.as< std::string > ().c_str(), 0));
+    yylhs.value.as< std::vector<dods_float64>* > () = yystack_[2].value.as< std::vector<dods_float64>* > ();
+}
+#line 1852 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 45:
+#line 418 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > () = yystack_[0].value.as< std::string > ();
+}
+#line 1860 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 46:
+#line 422 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > ().append("/");
+    yylhs.value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+}
+#line 1869 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 47:
+#line 427 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::string > ().append("/");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1879 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 48:
+#line 435 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > ().append("/");
+    yylhs.value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+}
+#line 1888 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 49:
+#line 440 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::string > ().append(".");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1898 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 50:
+#line 448 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > () = yystack_[0].value.as< std::string > ();
+}
+#line 1906 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 51:
+#line 452 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yystack_[2].value.as< std::string > ().append(".");
+    yystack_[2].value.as< std::string > ().append(yystack_[0].value.as< std::string > ());
+    yylhs.value.as< std::string > () = yystack_[2].value.as< std::string > ();
+}
+#line 1916 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 52:
+#line 463 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > ()=yystack_[0].value.as< std::string > ();
+}
+#line 1924 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+  case 53:
+#line 467 "d4_function_parser.yy" // lalr1.cc:846
+    {
+    yylhs.value.as< std::string > ()=yystack_[0].value.as< std::string > ();
+}
+#line 1932 "d4_function_parser.tab.cc" // lalr1.cc:846
+    break;
+
+
+#line 1936 "d4_function_parser.tab.cc" // lalr1.cc:846
+          default:
+            break;
+          }
+      }
+    catch (const syntax_error& yyexc)
+      {
+        error (yyexc);
+        YYERROR;
+      }
+    YY_SYMBOL_PRINT ("-> $$ =", yylhs);
+    yypop_ (yylen);
+    yylen = 0;
+    YY_STACK_PRINT ();
+
+    // Shift the result of the reduction.
+    yypush_ (YY_NULL, yylhs);
+    goto yynewstate;
+
+  /*--------------------------------------.
+  | yyerrlab -- here on detecting error.  |
+  `--------------------------------------*/
+  yyerrlab:
+    // If not already recovering from an error, report this error.
+    if (!yyerrstatus_)
+      {
+        ++yynerrs_;
+        error (yyla.location, yysyntax_error_ (yystack_[0].state,
+                                           yyempty ? yyempty_ : yyla.type_get ()));
+      }
+
+
+    yyerror_range[1].location = yyla.location;
+    if (yyerrstatus_ == 3)
+      {
+        /* If just tried and failed to reuse lookahead token after an
+           error, discard it.  */
+
+        // Return failure if at end of input.
+        if (yyla.type_get () == yyeof_)
+          YYABORT;
+        else if (!yyempty)
+          {
+            yy_destroy_ ("Error: discarding", yyla);
+            yyempty = true;
+          }
+      }
+
+    // Else will try to reuse lookahead 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 (false)
+      goto yyerrorlab;
+    yyerror_range[1].location = yystack_[yylen - 1].location;
+    /* $$ was initialized before running the user action.  */
+    YY_SYMBOL_PRINT ("Error: discarding", yylhs);
+    yylhs.~stack_symbol_type();
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYERROR.  */
+    yypop_ (yylen);
+    yylen = 0;
+    goto yyerrlab1;
+
+  /*-------------------------------------------------------------.
+  | yyerrlab1 -- common code for both syntax error and YYERROR.  |
+  `-------------------------------------------------------------*/
+  yyerrlab1:
+    yyerrstatus_ = 3;   // Each real token shifted decrements this.
+    {
+      stack_symbol_type error_token;
+      for (;;)
+        {
+          yyn = yypact_[yystack_[0].state];
+          if (!yy_pact_value_is_default_ (yyn))
+            {
+              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 (yystack_.size () == 1)
+            YYABORT;
+
+          yyerror_range[1].location = yystack_[0].location;
+          yy_destroy_ ("Error: popping", yystack_[0]);
+          yypop_ ();
+          YY_STACK_PRINT ();
+        }
+
+      yyerror_range[2].location = yyla.location;
+      YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);
+
+      // Shift the error token.
+      error_token.state = yyn;
+      yypush_ ("Shifting", error_token);
+    }
+    goto yynewstate;
+
+    // Accept.
+  yyacceptlab:
+    yyresult = 0;
+    goto yyreturn;
+
+    // Abort.
+  yyabortlab:
+    yyresult = 1;
+    goto yyreturn;
+
+  yyreturn:
+    if (!yyempty)
+      yy_destroy_ ("Cleanup: discarding lookahead", yyla);
+
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYABORT or YYACCEPT.  */
+    yypop_ (yylen);
+    while (1 < yystack_.size ())
+      {
+        yy_destroy_ ("Cleanup: popping", yystack_[0]);
+        yypop_ ();
+      }
+
+    return yyresult;
+  }
+    catch (...)
+      {
+        YYCDEBUG << "Exception caught: cleaning lookahead and stack"
+                 << std::endl;
+        // Do not try to display the values of the reclaimed symbols,
+        // as their printer might throw an exception.
+        if (!yyempty)
+          yy_destroy_ (YY_NULL, yyla);
+
+        while (1 < yystack_.size ())
+          {
+            yy_destroy_ (YY_NULL, yystack_[0]);
+            yypop_ ();
+          }
+        throw;
+      }
+  }
+
+  void
+  D4FunctionParser::error (const syntax_error& yyexc)
+  {
+    error (yyexc.location, yyexc.what());
+  }
+
+  // Generate an error message.
+  std::string
+  D4FunctionParser::yysyntax_error_ (state_type yystate, symbol_number_type yytoken) const
+  {
+    std::string yyres;
+    // Number of reported tokens (one for the "unexpected", one per
+    // "expected").
+    size_t yycount = 0;
+    // Its maximum.
+    enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+    // Arguments of yyformat.
+    char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+
+    /* There are many possibilities here to consider:
+       - If this state is a consistent state with a default action, then
+         the only way this function was invoked is if the default action
+         is an error action.  In that case, don't check for expected
+         tokens because there are none.
+       - The only way there can be no lookahead present (in yytoken) is
+         if this state is a consistent state with a default action.
+         Thus, detecting the absence of a lookahead is sufficient to
+         determine that there is no unexpected or expected token to
+         report.  In that case, just report a simple "syntax error".
+       - Don't assume there isn't a lookahead just because this state is
+         a consistent state with a default action.  There might have
+         been a previous inconsistent state, consistent state with a
+         non-default action, or user semantic action that manipulated
+         yyla.  (However, yyla is currently not documented for users.)
+       - Of course, the expected token list depends on states to have
+         correct lookahead information, and it depends on the parser not
+         to perform extra reductions after fetching a lookahead from the
+         scanner and before detecting a syntax error.  Thus, state
+         merging (from LALR or IELR) and default reductions corrupt the
+         expected token list.  However, the list is correct for
+         canonical LR with one exception: it will still contain any
+         token that will not be accepted due to an error action in a
+         later state.
+    */
+    if (yytoken != yyempty_)
+      {
+        yyarg[yycount++] = yytname_[yytoken];
+        int yyn = yypact_[yystate];
+        if (!yy_pact_value_is_default_ (yyn))
+          {
+            /* Start YYX at -YYN if negative to avoid negative indexes in
+               YYCHECK.  In other words, skip the first -YYN actions for
+               this state because they are default actions.  */
+            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_;
+            for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+              if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
+                  && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
+                {
+                  if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                    {
+                      yycount = 1;
+                      break;
+                    }
+                  else
+                    yyarg[yycount++] = yytname_[yyx];
+                }
+          }
+      }
+
+    char const* yyformat = YY_NULL;
+    switch (yycount)
+      {
+#define YYCASE_(N, S)                         \
+        case N:                               \
+          yyformat = S;                       \
+        break
+        YYCASE_(0, YY_("syntax error"));
+        YYCASE_(1, YY_("syntax error, unexpected %s"));
+        YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+        YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+        YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+        YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+#undef YYCASE_
+      }
+
+    // Argument number.
+    size_t yyi = 0;
+    for (char const* yyp = yyformat; *yyp; ++yyp)
+      if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
+        {
+          yyres += yytnamerr_ (yyarg[yyi++]);
+          ++yyp;
+        }
+      else
+        yyres += *yyp;
+    return yyres;
+  }
+
+
+  const signed char D4FunctionParser::yypact_ninf_ = -20;
+
+  const signed char D4FunctionParser::yytable_ninf_ = -50;
+
+  const signed char
+  D4FunctionParser::yypact_[] =
+  {
+     -10,   -20,     8,    10,   -20,    12,   -20,   -10,   -18,   -20,
+      37,   -20,   -16,    38,    39,    42,    43,    44,    45,    46,
+      47,    48,    49,    50,   -20,   -19,   -20,   -20,   -20,   -20,
+      51,    52,   -20,   -20,    52,    54,    55,    55,    55,    55,
+      55,    55,    55,    55,    55,    55,    55,   -20,   -18,   -16,
+     -16,   -20,    53,    56,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,   -20,    52,    68,   -20,    57,    57,    71,
+      72,    73,    74,    76,    77,    78,   -16,   -16,   -20,     9,
+      16,   -20,    18,   -20,    20,   -20,    22,   -20,    24,   -20,
+      26,   -20,    28,   -20,    30,    32,    52,    34,    52,   -20,
+      79,   -20,   -20,    80,   -20,    81,   -20,    82,   -20,    83,
+     -20,    84,   -20,    86,   -20,    88,   -20,   -16,   -20,   -16,
+     -20,   -20,   -20,   -20,   -20,   -20,   -20,   -20,    52,    52
+  };
+
+  const unsigned char
+  D4FunctionParser::yydefact_[] =
+  {
+       0,     6,     0,     2,     3,     0,     1,     0,     0,     4,
+      52,    53,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     9,     0,     7,    10,    11,    12,
+       0,    45,    50,    52,    46,    50,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     5,     0,     0,
+       0,    24,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     8,    47,    50,    51,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    25,     0,
+       0,    27,     0,    29,     0,    31,     0,    33,     0,    35,
+       0,    37,     0,    39,     0,     0,    41,     0,    43,    13,
+       0,    14,    15,     0,    16,     0,    17,     0,    18,     0,
+      19,     0,    20,     0,    21,     0,    22,     0,    23,     0,
+      26,    28,    30,    32,    34,    36,    38,    40,    42,    44
+  };
+
+  const signed char
+  D4FunctionParser::yypgoto_[] =
+  {
+     -20,   -20,   -20,    33,   -20,   -20,    69,   -20,   -20,   -15,
+      41,   -20,   -20,   -20,   -20,   -20,   -20,   -20,   -20,   -20,
+     -20,   -20,   -12,   -11
+  };
+
+  const signed char
+  D4FunctionParser::yydefgoto_[] =
+  {
+      -1,     2,     3,    24,     5,    25,    26,    27,    28,    52,
+      79,    82,    84,    86,    88,    90,    92,    94,    95,    97,
+      29,    30,    31,    32
+  };
+
+  const short int
+  D4FunctionParser::yytable_[] =
+  {
+      34,    35,    10,    11,    33,    11,    47,    48,     6,    12,
+       1,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    23,    53,    54,    55,    56,    57,    58,    59,    60,
+      61,    62,     7,     4,    99,   100,     8,    64,    65,    66,
+       9,   101,   100,   102,   103,   104,   105,   106,   107,   108,
+     109,   110,   111,   112,   113,   114,   115,   116,   117,   118,
+     119,    -6,    36,    37,    96,    98,    38,    39,    40,    41,
+      42,    43,    44,    45,    46,    51,    67,    78,    49,    68,
+      50,   -48,    69,    70,    71,    72,    73,    74,    75,    76,
+      77,    81,    83,    85,    87,   -49,    89,    91,    93,   120,
+     121,   122,   123,   124,   125,   128,   126,   129,   127,    80,
+       0,     0,     0,     0,     0,     0,     0,    63
+  };
+
+  const signed char
+  D4FunctionParser::yycheck_[] =
+  {
+      12,    12,    20,    21,    20,    21,    25,    26,     0,    27,
+      20,    29,    30,    31,    32,    33,    34,    35,    36,    37,
+      38,    39,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    22,     0,    25,    26,    24,    49,    49,    50,
+       7,    25,    26,    25,    26,    25,    26,    25,    26,    25,
+      26,    25,    26,    25,    26,    25,    26,    25,    26,    25,
+      26,    24,    24,    24,    76,    77,    24,    24,    24,    24,
+      24,    24,    24,    24,    24,    20,    23,    20,    27,    23,
+      28,    27,    23,    23,    23,    23,    23,    23,    23,    23,
+      23,    20,    20,    20,    20,    27,    20,    20,    20,    20,
+      20,    20,    20,    20,    20,   117,    20,   119,    20,    68,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    48
+  };
+
+  const unsigned char
+  D4FunctionParser::yystos_[] =
+  {
+       0,    20,    41,    42,    43,    44,     0,    22,    24,    43,
+      20,    21,    27,    29,    30,    31,    32,    33,    34,    35,
+      36,    37,    38,    39,    43,    45,    46,    47,    48,    60,
+      61,    62,    63,    20,    62,    63,    24,    24,    24,    24,
+      24,    24,    24,    24,    24,    24,    24,    25,    26,    27,
+      28,    20,    49,    49,    49,    49,    49,    49,    49,    49,
+      49,    49,    49,    46,    62,    63,    63,    23,    23,    23,
+      23,    23,    23,    23,    23,    23,    23,    23,    20,    50,
+      50,    20,    51,    20,    52,    20,    53,    20,    54,    20,
+      55,    20,    56,    20,    57,    58,    62,    59,    62,    25,
+      26,    25,    25,    26,    25,    26,    25,    26,    25,    26,
+      25,    26,    25,    26,    25,    26,    25,    26,    25,    26,
+      20,    20,    20,    20,    20,    20,    20,    20,    62,    62
+  };
+
+  const unsigned char
+  D4FunctionParser::yyr1_[] =
+  {
+       0,    40,    41,    42,    42,    43,    44,    45,    45,    46,
+      46,    46,    47,    48,    48,    48,    48,    48,    48,    48,
+      48,    48,    48,    48,    49,    50,    50,    51,    51,    52,
+      52,    53,    53,    54,    54,    55,    55,    56,    56,    57,
+      57,    58,    58,    59,    59,    60,    60,    60,    61,    61,
+      62,    62,    63,    63
+  };
+
+  const unsigned char
+  D4FunctionParser::yyr2_[] =
+  {
+       0,     2,     1,     1,     3,     4,     1,     1,     3,     1,
+       1,     1,     1,     6,     6,     6,     6,     6,     6,     6,
+       6,     6,     6,     6,     1,     1,     3,     1,     3,     1,
+       3,     1,     3,     1,     3,     1,     3,     1,     3,     1,
+       3,     1,     3,     1,     3,     1,     2,     3,     2,     3,
+       1,     3,     1,     1
+  };
+
+
+
+  // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+  // First, the terminals, then, starting at \a yyntokens_, nonterminals.
+  const char*
+  const D4FunctionParser::yytname_[] =
+  {
+  "\"end of file\"", "error", "$undefined", "\"functions\"",
+  "\"arguments\"", "\"argument\"", "\"function\"", "\"function name\"",
+  "\"variable or constant\"", "\"array constant\"",
+  "\"fast byte arg list\"", "\"fast int8 arg list\"",
+  "\"fast uint16 arg list\"", "\"fast int16 arg list\"",
+  "\"fast uint32 arg list\"", "\"fast int32 arg list\"",
+  "\"fast uint64 arg list\"", "\"fast int64 arg list\"",
+  "\"fast float32 arg list\"", "\"fast float64 arg list\"", "\"word\"",
+  "\"string\"", "\";\"", "\":\"", "\"(\"", "\")\"", "\",\"", "\"/\"",
+  "\".\"", "\"$Byte\"", "\"$UInt8\"", "\"$Int8\"", "\"$UInt16\"",
+  "\"$Int16\"", "\"$UInt32\"", "\"$Int32\"", "\"$UInt64\"", "\"$Int64\"",
+  "\"$Float32\"", "\"$Float64\"", "$accept", "program", "functions",
+  "function", "fname", "args", "arg", "variable_or_constant",
+  "array_constant", "arg_length_hint", "fast_byte_arg_list",
+  "fast_int8_arg_list", "fast_uint16_arg_list", "fast_int16_arg_list",
+  "fast_uint32_arg_list", "fast_int32_arg_list", "fast_uint64_arg_list",
+  "fast_int64_arg_list", "fast_float32_arg_list", "fast_float64_arg_list",
+  "id", "group", "path", "name", YY_NULL
+  };
+
+#if YYDEBUG
+  const unsigned short int
+  D4FunctionParser::yyrline_[] =
+  {
+       0,   155,   155,   161,   165,   172,   178,   190,   194,   201,
+     205,   209,   215,   227,   233,   239,   245,   251,   257,   263,
+     269,   275,   281,   287,   299,   305,   309,   316,   320,   327,
+     331,   338,   342,   349,   353,   359,   363,   370,   374,   381,
+     385,   395,   399,   406,   410,   417,   421,   426,   434,   439,
+     447,   451,   462,   466
+  };
+
+  // Print the state stack on the debug stream.
+  void
+  D4FunctionParser::yystack_print_ ()
+  {
+    *yycdebug_ << "Stack now";
+    for (stack_type::const_iterator
+           i = yystack_.begin (),
+           i_end = yystack_.end ();
+         i != i_end; ++i)
+      *yycdebug_ << ' ' << i->state;
+    *yycdebug_ << std::endl;
+  }
+
+  // Report on the debug stream that the rule \a yyrule is going to be reduced.
+  void
+  D4FunctionParser::yy_reduce_print_ (int yyrule)
+  {
+    unsigned int yylno = yyrline_[yyrule];
+    int yynrhs = yyr2_[yyrule];
+    // Print the symbols being reduced, and their result.
+    *yycdebug_ << "Reducing stack by rule " << yyrule - 1
+               << " (line " << yylno << "):" << std::endl;
+    // The symbols being reduced.
+    for (int yyi = 0; yyi < yynrhs; yyi++)
+      YY_SYMBOL_PRINT ("   $" << yyi + 1 << " =",
+                       yystack_[(yynrhs) - (yyi + 1)]);
+  }
+#endif // YYDEBUG
+
+  // Symbol number corresponding to token number t.
+  inline
+  D4FunctionParser::token_number_type
+  D4FunctionParser::yytranslate_ (int t)
+  {
+    static
+    const token_number_type
+    translate_table[] =
+    {
+     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,    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
+    };
+    const unsigned int user_token_number_max_ = 294;
+    const token_number_type undef_token_ = 2;
+
+    if (static_cast<int>(t) <= yyeof_)
+      return yyeof_;
+    else if (static_cast<unsigned int> (t) <= user_token_number_max_)
+      return translate_table[t];
+    else
+      return undef_token_;
+  }
+
+#line 34 "d4_function_parser.yy" // lalr1.cc:1156
+} // libdap
+#line 2444 "d4_function_parser.tab.cc" // lalr1.cc:1156
+#line 472 "d4_function_parser.yy" // lalr1.cc:1157
+
+
+// Forward the error to the driver for handling. The location parameter
+// provides the line number and character position of the error.
+void
+libdap::D4FunctionParser::error(const location_type &l, const std::string &m)
+{
+    evaluator.error(l, m);
+}
+
+/* include for access to scanner.yylex */
+#include "D4FunctionScanner.h"
+
+static int yylex(libdap::D4FunctionParser::semantic_type *yylval,
+                 libdap::location *loc,
+                 libdap::D4FunctionScanner &scanner,
+                 libdap::D4FunctionEvaluator &evaluator)
+{
+    if (evaluator.trace_scanning())
+        scanner.set_debug(true);
+    
+    return( scanner.yylex(yylval, loc) );
+}
diff --git a/d4_ce/gen_grammar_sources/d4_function_parser.tab.hh.tmp b/d4_ce/gen_grammar_sources/d4_function_parser.tab.hh.tmp
new file mode 100644
index 0000000..bbb3b32
--- /dev/null
+++ b/d4_ce/gen_grammar_sources/d4_function_parser.tab.hh.tmp
@@ -0,0 +1,783 @@
+// A Bison parser, made by GNU Bison 3.0.
+
+// Skeleton interface for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file d4_function_parser.tab.hh
+ ** Define the libdap::parser class.
+ */
+
+// C++ LALR(1) parser skeleton written by Akim Demaille.
+
+#ifndef YY_YY_D4_FUNCTION_PARSER_TAB_HH_INCLUDED
+# define YY_YY_D4_FUNCTION_PARSER_TAB_HH_INCLUDED
+// //                    "%code requires" blocks.
+#line 47 "d4_function_parser.yy" // lalr1.cc:386
+
+
+#include "D4FunctionEvaluator.h"
+#include "D4RValue.h"
+#include "dods-datatypes.h"
+
+namespace libdap {
+    class D4FunctionScanner;
+}
+
+
+#line 56 "d4_function_parser.tab.hh" // lalr1.cc:386
+
+# include <cassert>
+# include <vector>
+# include <iostream>
+# include <stdexcept>
+# include <string>
+# include "stack.hh"
+# include "location.hh"
+#include <typeinfo>
+#ifndef YYASSERT
+# include <cassert>
+# define YYASSERT assert
+#endif
+
+
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+
+#line 34 "d4_function_parser.yy" // lalr1.cc:386
+namespace libdap {
+#line 79 "d4_function_parser.tab.hh" // lalr1.cc:386
+
+
+
+  /// A char[S] buffer to store and retrieve objects.
+  ///
+  /// Sort of a variant, but does not keep track of the nature
+  /// of the stored data, since that knowledge is available
+  /// via the current state.
+  template <size_t S>
+  struct variant
+  {
+    /// Type of *this.
+    typedef variant<S> self_type;
+
+    /// Empty construction.
+    variant ()
+      : yytname_ (YY_NULL)
+    {}
+
+    /// Construct and fill.
+    template <typename T>
+    variant (const T& t)
+      : yytname_ (typeid (T).name ())
+    {
+      YYASSERT (sizeof (T) <= S);
+      new (yyas_<T> ()) T (t);
+    }
+
+    /// Destruction, allowed only if empty.
+    ~variant ()
+    {
+      YYASSERT (!yytname_);
+    }
+
+    /// Instantiate an empty \a T in here.
+    template <typename T>
+    T&
+    build ()
+    {
+      YYASSERT (!yytname_);
+      YYASSERT (sizeof (T) <= S);
+      yytname_ = typeid (T).name ();
+      return *new (yyas_<T> ()) T;
+    }
+
+    /// Instantiate a \a T in here from \a t.
+    template <typename T>
+    T&
+    build (const T& t)
+    {
+      YYASSERT (!yytname_);
+      YYASSERT (sizeof (T) <= S);
+      yytname_ = typeid (T).name ();
+      return *new (yyas_<T> ()) T (t);
+    }
+
+    /// Accessor to a built \a T.
+    template <typename T>
+    T&
+    as ()
+    {
+      YYASSERT (yytname_ == typeid (T).name ());
+      YYASSERT (sizeof (T) <= S);
+      return *yyas_<T> ();
+    }
+
+    /// Const accessor to a built \a T (for %printer).
+    template <typename T>
+    const T&
+    as () const
+    {
+      YYASSERT (yytname_ == typeid (T).name ());
+      YYASSERT (sizeof (T) <= S);
+      return *yyas_<T> ();
+    }
+
+    /// Swap the content with \a other, of same type.
+    ///
+    /// Both variants must be built beforehand, because swapping the actual
+    /// data requires reading it (with as()), and this is not possible on
+    /// unconstructed variants: it would require some dynamic testing, which
+    /// should not be the variant's responsability.
+    /// Swapping between built and (possibly) non-built is done with
+    /// variant::move ().
+    template <typename T>
+    void
+    swap (self_type& other)
+    {
+      YYASSERT (yytname_);
+      YYASSERT (yytname_ == other.yytname_);
+      std::swap (as<T> (), other.as<T> ());
+    }
+
+    /// Move the content of \a other to this.
+    ///
+    /// Destroys \a other.
+    template <typename T>
+    void
+    move (self_type& other)
+    {
+      YYASSERT (!yytname_);
+      build<T> ();
+      swap<T> (other);
+      other.destroy<T> ();
+    }
+
+    /// Copy the content of \a other to this.
+    template <typename T>
+    void
+    copy (const self_type& other)
+    {
+      build<T> (other.as<T> ());
+    }
+
+    /// Destroy the stored \a T.
+    template <typename T>
+    void
+    destroy ()
+    {
+      as<T> ().~T ();
+      yytname_ = YY_NULL;
+    }
+
+  private:
+    /// Prohibit blind copies.
+    self_type& operator=(const self_type&);
+    variant (const self_type&);
+
+    /// Accessor to raw memory as \a T.
+    template <typename T>
+    T*
+    yyas_ ()
+    {
+      void *yyp = yybuffer_.yyraw;
+      return static_cast<T*> (yyp);
+     }
+
+    /// Const accessor to raw memory as \a T.
+    template <typename T>
+    const T*
+    yyas_ () const
+    {
+      const void *yyp = yybuffer_.yyraw;
+      return static_cast<const T*> (yyp);
+     }
+
+    union
+    {
+      /// Strongest alignment constraints.
+      long double yyalign_me;
+      /// A buffer large enough to store any of the semantic values.
+      char yyraw[S];
+    } yybuffer_;
+
+    /// Whether the content is built: if defined, the name of the stored type.
+    const char *yytname_;
+  };
+
+
+  /// A Bison parser.
+  class D4FunctionParser
+  {
+  public:
+#ifndef YYSTYPE
+    /// An auxiliary type to compute the largest semantic type.
+    union union_type
+    {
+      // "function name"
+      // fname
+      char dummy1[sizeof(D4Function)];
+
+      // "argument"
+      // "function"
+      // "variable or constant"
+      // "array constant"
+      // function
+      // arg
+      // variable_or_constant
+      // array_constant
+      char dummy2[sizeof(D4RValue*)];
+
+      // "functions"
+      // "arguments"
+      // functions
+      // args
+      char dummy3[sizeof(D4RValueList*)];
+
+      // "word"
+      // "string"
+      // id
+      // group
+      // path
+      // name
+      char dummy4[sizeof(std::string)];
+
+      // "fast byte arg list"
+      // fast_byte_arg_list
+      char dummy5[sizeof(std::vector<dods_byte>*)];
+
+      // "fast float32 arg list"
+      // fast_float32_arg_list
+      char dummy6[sizeof(std::vector<dods_float32>*)];
+
+      // "fast float64 arg list"
+      // fast_float64_arg_list
+      char dummy7[sizeof(std::vector<dods_float64>*)];
+
+      // "fast int16 arg list"
+      // fast_int16_arg_list
+      char dummy8[sizeof(std::vector<dods_int16>*)];
+
+      // "fast int32 arg list"
+      // fast_int32_arg_list
+      char dummy9[sizeof(std::vector<dods_int32>*)];
+
+      // "fast int64 arg list"
+      // fast_int64_arg_list
+      char dummy10[sizeof(std::vector<dods_int64>*)];
+
+      // "fast int8 arg list"
+      // fast_int8_arg_list
+      char dummy11[sizeof(std::vector<dods_int8>*)];
+
+      // "fast uint16 arg list"
+      // fast_uint16_arg_list
+      char dummy12[sizeof(std::vector<dods_uint16>*)];
+
+      // "fast uint32 arg list"
+      // fast_uint32_arg_list
+      char dummy13[sizeof(std::vector<dods_uint32>*)];
+
+      // "fast uint64 arg list"
+      // fast_uint64_arg_list
+      char dummy14[sizeof(std::vector<dods_uint64>*)];
+};
+
+    /// Symbol semantic values.
+    typedef variant<sizeof(union_type)> semantic_type;
+#else
+    typedef YYSTYPE semantic_type;
+#endif
+    /// Symbol locations.
+    typedef location location_type;
+
+    /// Syntax errors thrown from user actions.
+    struct syntax_error : std::runtime_error
+    {
+      syntax_error (const location_type& l, const std::string& m);
+      location_type location;
+    };
+
+    /// Tokens.
+    struct token
+    {
+      enum yytokentype
+      {
+        END = 0,
+        WORD = 275,
+        STRING = 276,
+        SEMICOLON = 277,
+        COLON = 278,
+        LPAREN = 279,
+        RPAREN = 280,
+        COMMA = 281,
+        GROUP_SEP = 282,
+        PATH_SEP = 283,
+        DOLLAR_BYTE = 284,
+        DOLLAR_UINT8 = 285,
+        DOLLAR_INT8 = 286,
+        DOLLAR_UINT16 = 287,
+        DOLLAR_INT16 = 288,
+        DOLLAR_UINT32 = 289,
+        DOLLAR_INT32 = 290,
+        DOLLAR_UINT64 = 291,
+        DOLLAR_INT64 = 292,
+        DOLLAR_FLOAT32 = 293,
+        DOLLAR_FLOAT64 = 294
+      };
+    };
+
+    /// (External) token type, as returned by yylex.
+    typedef token::yytokentype token_type;
+
+    /// Internal symbol number.
+    typedef int symbol_number_type;
+
+    /// Internal symbol number for tokens (subsumed by symbol_number_type).
+    typedef unsigned char token_number_type;
+
+    /// A complete symbol.
+    ///
+    /// Expects its Base type to provide access to the symbol type
+    /// via type_get().
+    ///
+    /// Provide access to semantic value and location.
+    template <typename Base>
+    struct basic_symbol : Base
+    {
+      /// Alias to Base.
+      typedef Base super_type;
+
+      /// Default constructor.
+      basic_symbol ();
+
+      /// Copy constructor.
+      basic_symbol (const basic_symbol& other);
+
+      /// Constructor for valueless symbols, and symbols from each type.
+
+  basic_symbol (typename Base::kind_type t, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const D4Function v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const D4RValue* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const D4RValueList* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_byte>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_float32>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_float64>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_int16>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_int32>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_int64>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_int8>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_uint16>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_uint32>* v, const location_type& l);
+
+  basic_symbol (typename Base::kind_type t, const std::vector<dods_uint64>* v, const location_type& l);
+
+
+      /// Constructor for symbols with semantic value.
+      basic_symbol (typename Base::kind_type t,
+                    const semantic_type& v,
+                    const location_type& l);
+
+      ~basic_symbol ();
+
+      /// Destructive move, \a s is emptied into this.
+      void move (basic_symbol& s);
+
+      /// The semantic value.
+      semantic_type value;
+
+      /// The location.
+      location_type location;
+
+    private:
+      /// Assignment operator.
+      basic_symbol& operator= (const basic_symbol& other);
+    };
+
+    /// Type access provider for token (enum) based symbols.
+    struct by_type
+    {
+      /// Default constructor.
+      by_type ();
+
+      /// Copy constructor.
+      by_type (const by_type& other);
+
+      /// The symbol type as needed by the constructor.
+      typedef token_type kind_type;
+
+      /// Constructor from (external) token numbers.
+      by_type (kind_type t);
+
+      /// Steal the symbol type from \a that.
+      void move (by_type& that);
+
+      /// The (internal) type number (corresponding to \a type).
+      /// -1 when this symbol is empty.
+      symbol_number_type type_get () const;
+
+      /// The token.
+      token_type token () const;
+
+      enum { empty = 0 };
+
+      /// The symbol type.
+      /// -1 when this symbol is empty.
+      token_number_type type;
+    };
+
+    /// "External" symbols: returned by the scanner.
+    typedef basic_symbol<by_type> symbol_type;
+
+    // Symbol constructors declarations.
+    static inline
+    symbol_type
+    make_END (const location_type& l);
+
+    static inline
+    symbol_type
+    make_WORD (const std::string& v, const location_type& l);
+
+    static inline
+    symbol_type
+    make_STRING (const std::string& v, const location_type& l);
+
+    static inline
+    symbol_type
+    make_SEMICOLON (const location_type& l);
+
+    static inline
+    symbol_type
+    make_COLON (const location_type& l);
+
+    static inline
+    symbol_type
+    make_LPAREN (const location_type& l);
+
+    static inline
+    symbol_type
+    make_RPAREN (const location_type& l);
+
+    static inline
+    symbol_type
+    make_COMMA (const location_type& l);
+
+    static inline
+    symbol_type
+    make_GROUP_SEP (const location_type& l);
+
+    static inline
+    symbol_type
+    make_PATH_SEP (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_BYTE (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_UINT8 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_INT8 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_UINT16 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_INT16 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_UINT32 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_INT32 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_UINT64 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_INT64 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_FLOAT32 (const location_type& l);
+
+    static inline
+    symbol_type
+    make_DOLLAR_FLOAT64 (const location_type& l);
+
+
+    /// Build a parser object.
+    D4FunctionParser (D4FunctionScanner  &scanner_yyarg, D4FunctionEvaluator  &evaluator_yyarg);
+    virtual ~D4FunctionParser ();
+
+    /// Parse.
+    /// \returns  0 iff parsing succeeded.
+    virtual int parse ();
+
+#if YYDEBUG
+    /// The current debugging stream.
+    std::ostream& debug_stream () const;
+    /// Set the current debugging stream.
+    void set_debug_stream (std::ostream &);
+
+    /// Type for debugging levels.
+    typedef int debug_level_type;
+    /// The current debugging level.
+    debug_level_type debug_level () const;
+    /// Set the current debugging level.
+    void set_debug_level (debug_level_type l);
+#endif
+
+    /// Report a syntax error.
+    /// \param loc    where the syntax error is found.
+    /// \param msg    a description of the syntax error.
+    virtual void error (const location_type& loc, const std::string& msg);
+
+    /// Report a syntax error.
+    void error (const syntax_error& err);
+
+  private:
+    /// This class is not copyable.
+    D4FunctionParser (const D4FunctionParser&);
+    D4FunctionParser& operator= (const D4FunctionParser&);
+
+    /// State numbers.
+    typedef int state_type;
+
+    /// Generate an error message.
+    /// \param yystate   the state where the error occurred.
+    /// \param yytoken   the lookahead token type, or yyempty_.
+    virtual std::string yysyntax_error_ (state_type yystate,
+                                         symbol_number_type yytoken) const;
+
+    /// Compute post-reduction state.
+    /// \param yystate   the current state
+    /// \param yylhs     the nonterminal to push on the stack
+    state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
+
+    /// Whether the given \c yypact_ value indicates a defaulted state.
+    /// \param yyvalue   the value to check
+    static bool yy_pact_value_is_default_ (int yyvalue);
+
+    /// Whether the given \c yytable_ value indicates a syntax error.
+    /// \param yyvalue   the value to check
+    static bool yy_table_value_is_error_ (int yyvalue);
+
+    static const signed char yypact_ninf_;
+    static const signed char yytable_ninf_;
+
+    /// Convert a scanner token number \a t to a symbol number.
+    static token_number_type yytranslate_ (int t);
+
+    // Tables.
+  // YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+  // STATE-NUM.
+  static const signed char yypact_[];
+
+  // YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+  // Performed when YYTABLE does not specify something else to do.  Zero
+  // means the default is an error.
+  static const unsigned char yydefact_[];
+
+  // YYPGOTO[NTERM-NUM].
+  static const signed char yypgoto_[];
+
+  // YYDEFGOTO[NTERM-NUM].
+  static const signed char yydefgoto_[];
+
+  // YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+  // positive, shift that token.  If negative, reduce the rule whose
+  // number is the opposite.  If YYTABLE_NINF, syntax error.
+  static const short int yytable_[];
+
+  static const signed char yycheck_[];
+
+  // YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+  // symbol of state STATE-NUM.
+  static const unsigned char yystos_[];
+
+  // YYR1[YYN] -- Symbol number of symbol that rule YYN derives.
+  static const unsigned char yyr1_[];
+
+  // YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.
+  static const unsigned char yyr2_[];
+
+
+    /// Convert the symbol name \a n to a form suitable for a diagnostic.
+    static std::string yytnamerr_ (const char *n);
+
+
+    /// For a symbol, its name in clear.
+    static const char* const yytname_[];
+#if YYDEBUG
+  // YYRLINE[YYN] -- Source line where rule number YYN was defined.
+  static const unsigned short int yyrline_[];
+    /// Report on the debug stream that the rule \a r is going to be reduced.
+    virtual void yy_reduce_print_ (int r);
+    /// Print the state stack on the debug stream.
+    virtual void yystack_print_ ();
+
+    // Debugging.
+    int yydebug_;
+    std::ostream* yycdebug_;
+
+    /// \brief Display a symbol type, value and location.
+    /// \param yyo    The output stream.
+    /// \param yysym  The symbol.
+    template <typename Base>
+    void yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const;
+#endif
+
+    /// \brief Reclaim the memory associated to a symbol.
+    /// \param yymsg     Why this token is reclaimed.
+    ///                  If null, print nothing.
+    /// \param s         The symbol.
+    template <typename Base>
+    void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
+
+  private:
+    /// Type access provider for state based symbols.
+    struct by_state
+    {
+      /// Default constructor.
+      by_state ();
+
+      /// The symbol type as needed by the constructor.
+      typedef state_type kind_type;
+
+      /// Constructor.
+      by_state (kind_type s);
+
+      /// Copy constructor.
+      by_state (const by_state& other);
+
+      /// Steal the symbol type from \a that.
+      void move (by_state& that);
+
+      /// The (internal) type number (corresponding to \a state).
+      /// "empty" when empty.
+      symbol_number_type type_get () const;
+
+      enum { empty = 0 };
+
+      /// The state.
+      state_type state;
+    };
+
+    /// "Internal" symbol: element of the stack.
+    struct stack_symbol_type : basic_symbol<by_state>
+    {
+      /// Superclass.
+      typedef basic_symbol<by_state> super_type;
+      /// Construct an empty symbol.
+      stack_symbol_type ();
+      /// Steal the contents from \a sym to build this.
+      stack_symbol_type (state_type s, symbol_type& sym);
+      /// Assignment, needed by push_back.
+      stack_symbol_type& operator= (const stack_symbol_type& that);
+    };
+
+    /// Stack type.
+    typedef stack<stack_symbol_type> stack_type;
+
+    /// The stack.
+    stack_type yystack_;
+
+    /// Push a new state on the stack.
+    /// \param m    a debug message to display
+    ///             if null, no trace is output.
+    /// \param s    the symbol
+    /// \warning the contents of \a s.value is stolen.
+    void yypush_ (const char* m, stack_symbol_type& s);
+
+    /// Push a new look ahead token on the state on the stack.
+    /// \param m    a debug message to display
+    ///             if null, no trace is output.
+    /// \param s    the state
+    /// \param sym  the symbol (for its value and location).
+    /// \warning the contents of \a s.value is stolen.
+    void yypush_ (const char* m, state_type s, symbol_type& sym);
+
+    /// Pop \a n symbols the three stacks.
+    void yypop_ (unsigned int n = 1);
+
+    // Constants.
+    enum
+    {
+      yyeof_ = 0,
+      yylast_ = 117,           //< Last index in yytable_.
+      yynnts_ = 24,  //< Number of nonterminal symbols.
+      yyempty_ = -2,
+      yyfinal_ = 6, //< Termination state number.
+      yyterror_ = 1,
+      yyerrcode_ = 256,
+      yyntokens_ = 40    //< Number of tokens.
+    };
+
+
+    // User arguments.
+    D4FunctionScanner  &scanner;
+    D4FunctionEvaluator  &evaluator;
+  };
+
+
+#line 34 "d4_function_parser.yy" // lalr1.cc:386
+} // libdap
+#line 779 "d4_function_parser.tab.hh" // lalr1.cc:386
+
+
+
+
+#endif // !YY_YY_D4_FUNCTION_PARSER_TAB_HH_INCLUDED
diff --git a/lex.ce_expr.cc b/d4_ce/gen_grammar_sources/lex.d4_ce.cc.tmp
similarity index 55%
copy from lex.ce_expr.cc
copy to d4_ce/gen_grammar_sources/lex.d4_ce.cc.tmp
index 8d2a9d6..becb9bd 100644
--- a/lex.ce_expr.cc
+++ b/d4_ce/gen_grammar_sources/lex.d4_ce.cc.tmp
@@ -1,29 +1,17 @@
-#line 2 "lex.ce_expr.cc"
 
-#line 4 "lex.ce_expr.cc"
+#line 3 "lex.d4_ce.cc"
 
 #define  YY_INT_ALIGNED short int
 
 /* A lexical scanner generated by flex */
 
-#define yy_create_buffer ce_expr_create_buffer
-#define yy_delete_buffer ce_expr_delete_buffer
-#define yy_flex_debug ce_expr_flex_debug
-#define yy_init_buffer ce_expr_init_buffer
-#define yy_flush_buffer ce_expr_flush_buffer
-#define yy_load_buffer_state ce_expr_load_buffer_state
-#define yy_switch_to_buffer ce_expr_switch_to_buffer
-#define yyin ce_exprin
-#define yyleng ce_exprleng
-#define yylex ce_exprlex
-#define yylineno ce_exprlineno
-#define yyout ce_exprout
-#define yyrestart ce_exprrestart
-#define yytext ce_exprtext
-#define yywrap ce_exprwrap
-#define yyalloc ce_expralloc
-#define yyrealloc ce_exprrealloc
-#define yyfree ce_exprfree
+/* %not-for-header */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+/* %endif */
+/* %endif */
+/* %ok-for-header */
 
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
@@ -33,16 +21,33 @@
 #define FLEX_BETA
 #endif
 
+/* %if-c++-only */
+    /* The c++ scanner is a mess. The FlexLexer.h header file relies on the
+     * following macro. This is required in order to pass the c++-multiple-scanners
+     * test in the regression suite. We get reports that it breaks inheritance.
+     * We will address this in a future release of flex, or omit the C++ scanner
+     * altogether.
+     */
+    #define yyFlexLexer d4_ceFlexLexer
+/* %endif */
+
+/* %if-c-only */
+/* %endif */
+
+/* %if-c-only */
+/* %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>
+/* %if-c-only */
+/* %endif */
 
+/* %if-tables-serialization */
+/* %endif */
 /* end standard C headers. */
 
+/* %if-c-or-c++ */
 /* flex integer type definitions */
 
 #ifndef FLEXINT_H
@@ -66,6 +71,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -106,6 +112,17 @@ typedef unsigned int flex_uint32_t;
 
 #endif /* ! FLEXINT_H */
 
+/* %endif */
+
+/* %if-c++-only */
+/* begin standard C++ headers. */
+#include <iostream> 
+#include <errno.h>
+#include <cstdlib>
+#include <cstring>
+/* end standard C++ headers. */
+/* %endif */
+
 #ifdef __cplusplus
 
 /* The "const" storage-class-modifier is valid. */
@@ -127,8 +144,13 @@ typedef unsigned int flex_uint32_t;
 #define yyconst
 #endif
 
+/* %not-for-header */
+
 /* Returned upon end-of-file. */
 #define YY_NULL 0
+/* %ok-for-header */
+
+/* %not-for-header */
 
 /* Promotes a possibly negative, possibly signed char to an unsigned
  * integer for use as an array index.  If the signed char is negative,
@@ -136,6 +158,14 @@ typedef unsigned int flex_uint32_t;
  * double cast.
  */
 #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+/* %ok-for-header */
+
+/* %if-reentrant */
+/* %endif */
+
+/* %if-not-reentrant */
+
+/* %endif */
 
 /* 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
@@ -154,7 +184,7 @@ typedef unsigned int flex_uint32_t;
 #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_NEW_FILE yyrestart( yyin  )
 
 #define YY_END_OF_BUFFER_CHAR 0
 
@@ -172,42 +202,65 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int ce_exprleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
 
-extern FILE *ce_exprin, *ce_exprout;
+/* %if-not-reentrant */
+extern yy_size_t yyleng;
+/* %endif */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+/* %endif */
+/* %endif */
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
 
-    #define YY_LESS_LINENO(n)
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+     *       access to the local variable yy_act. Since yyless() is a macro, it would break
+     *       existing scanners that call yyless() from OUTSIDE yylex. 
+     *       One obvious solution it to make yy_act a global. I tried that, and saw
+     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                yy_size_t yyl;\
+                for ( yyl = n; yyl < yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
     
 /* Return all but the first "n" matched characters back to the input stream. */
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ce_exprtext. */ \
+		/* Undo effects of setting up yytext. */ \
         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 */ \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
 		} \
 	while ( 0 )
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
 	{
-	FILE *yy_input_file;
+/* %if-c-only */
+/* %endif */
+
+/* %if-c++-only */
+	std::istream* yy_input_file;
+/* %endif */
 
 	char *yy_ch_buf;		/* input buffer */
 	char *yy_buf_pos;		/* current position in input buffer */
@@ -220,7 +273,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t 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
@@ -260,18 +313,22 @@ struct yy_buffer_state
 	 * 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.
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin 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. */
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+/* %if-not-reentrant */
+/* %endif */
+/* %ok-for-header */
+
+/* %endif */
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
@@ -288,51 +345,27 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
  */
 #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 );
+/* %if-c-only Standard (non-C++) definition */
+/* %if-not-reentrant */
+/* %not-for-header */
 
-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  );
+/* %ok-for-header */
 
-#define YY_FLUSH_BUFFER ce_expr_flush_buffer(YY_CURRENT_BUFFER )
+/* %endif */
+/* %endif */
 
-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 *d4_cealloc (yy_size_t  );
+void *d4_cerealloc (void *,yy_size_t  );
+void d4_cefree (void *  );
 
-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_new_buffer yy_create_buffer
 
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
-        ce_exprensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
@@ -340,49 +373,53 @@ void ce_exprfree (void *  );
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
-        ce_exprensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
 
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
+/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
 /* Begin user sect3 */
-
-#define ce_exprwrap(n) 1
 #define YY_SKIP_YYWRAP
 
-typedef unsigned char YY_CHAR;
+#define FLEX_DEBUG
 
-FILE *ce_exprin = (FILE *) 0, *ce_exprout = (FILE *) 0;
+typedef unsigned char YY_CHAR;
 
-typedef int yy_state_type;
+#define yytext_ptr yytext
 
-extern int ce_exprlineno;
+#include <FlexLexer.h>
 
-int ce_exprlineno = 1;
+int yyFlexLexer::yywrap() { return 1; }
+int yyFlexLexer::yylex()
+	{
+	LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" );
+	return 0;
+	}
 
-extern char *ce_exprtext;
-#define yytext_ptr ce_exprtext
+#define YY_DECL int D4CEScanner::yylex()
 
-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[]  );
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
 
 /* Done after the current pattern has been matched and before the
- * corresponding action - sets up ce_exprtext.
+ * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\
 	(yytext_ptr) -= (yy_more_len); \
-	ce_exprleng = (size_t) (yy_cp - (yytext_ptr)); \
+	yyleng = (yy_size_t) (yy_cp - (yytext_ptr)); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
+/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
 	(yy_c_buf_p) = yy_cp;
 
+/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
 #define YY_NUM_RULES 32
 #define YY_END_OF_BUFFER 33
 /* This struct is not used in this scanner,
@@ -392,33 +429,31 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[66] =
+static yyconst flex_int16_t yy_accept[46] =
     {   0,
-        0,    0,   28,   28,   33,   31,   26,   31,   27,   31,
-       10,    5,    6,    7,   18,    4,    3,   15,   11,   13,
-        1,    2,    8,    9,   32,   28,   30,   32,   26,   12,
-        0,    0,    0,    0,   10,   16,   17,   14,   28,   29,
-        0,    0,    0,    0,    0,    0,    0,    0,   19,    0,
-        0,    0,    0,    0,   20,   22,    0,    0,    0,    0,
-       21,   23,   24,   25,    0
+        0,    0,   26,   26,   33,   31,   22,   23,   23,   24,
+       25,   24,    4,   10,    9,    3,    5,   16,   11,   14,
+       24,    1,    2,    7,    6,    8,   24,   26,   30,   29,
+       22,   23,   24,   13,   19,   17,   12,   15,   20,   21,
+       18,   26,   27,   28,    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,    4,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    4,    5,    6,    7,    8,    9,    1,   10,
-       11,   12,    8,   13,    8,    8,    8,    8,   14,   15,
-       16,   17,    8,   18,    8,    8,    8,   19,    1,   20,
-       21,   22,    1,    1,    8,   23,    8,    8,    8,   24,
-        8,    8,   25,    8,    8,    8,    8,    8,    8,    8,
-        8,    8,    8,    8,   26,    8,    8,    8,    8,    8,
-       27,   28,   29,    1,    8,    1,   30,    8,    8,    8,
-
-       31,    8,    8,    8,    8,    8,    8,   32,    8,   33,
-       34,    8,    8,    8,    8,   35,    8,    8,    8,    8,
-       36,    8,   37,    1,   38,   39,    1,    1,    1,    1,
+        1,    2,    5,    6,    7,    1,    8,    1,    1,    1,
+        1,    8,    8,    9,    8,   10,   11,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,   12,   13,   14,
+       15,   16,    1,   17,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+       18,   19,   20,    1,    8,    1,    8,    8,    8,    8,
+
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,   21,   22,   23,   24,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -435,98 +470,86 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[40] =
+static yyconst flex_int32_t yy_meta[25] =
     {   0,
-        1,    1,    2,    1,    3,    4,    1,    4,    1,    1,
-        1,    1,    1,    4,    4,    4,    4,    4,    1,    1,
-        1,    1,    4,    4,    4,    4,    1,    5,    1,    4,
-        4,    4,    4,    4,    4,    4,    1,    1,    1
+        1,    1,    1,    1,    2,    3,    2,    2,    1,    1,
+        1,    1,    1,    1,    2,    1,    2,    1,    4,    1,
+        1,    1,    1,    2
     } ;
 
-static yyconst flex_int16_t yy_base[70] =
+static yyconst flex_int16_t yy_base[49] =
     {   0,
-        0,    0,   35,   36,   94,   95,   40,   72,   95,   21,
-        0,   95,   95,   95,   95,   95,   95,   71,   52,   69,
-       95,   95,   95,   95,   95,    0,   95,    0,   46,   95,
-       53,   56,   54,   61,    0,   95,   95,   95,    0,   95,
-       50,   50,   48,   49,   50,   47,   36,   39,   95,   27,
-       43,   45,   37,   38,   95,   95,   41,   43,   42,   38,
-       95,   95,   95,   95,   95,   64,   66,   71,   75
+        0,    0,   19,   20,   54,   58,   45,   24,   26,   31,
+       58,   30,   58,   58,   58,   58,   58,   17,   29,   18,
+       28,   58,   58,   58,   58,   58,   27,    0,   58,   29,
+       39,   33,   25,   58,   58,   58,   58,   58,   58,   58,
+       58,    0,   58,   58,   58,   48,   51,   55
     } ;
 
-static yyconst flex_int16_t yy_def[70] =
+static yyconst flex_int16_t yy_def[49] =
     {   0,
-       65,    1,   66,   66,   65,   65,   65,   65,   65,   65,
-       67,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   68,   65,   69,   65,   65,
-       65,   65,   65,   65,   67,   65,   65,   65,   68,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,    0,   65,   65,   65,   65
+       45,    1,   46,   46,   45,   45,   45,   45,   45,   47,
+       45,   47,   45,   45,   45,   45,   45,   45,   45,   45,
+       47,   45,   45,   45,   45,   45,   47,   48,   45,   45,
+       45,   45,   47,   45,   45,   45,   45,   45,   45,   45,
+       45,   48,   45,   45,    0,   45,   45,   45
     } ;
 
-static yyconst flex_int16_t yy_nxt[135] =
+static yyconst flex_int16_t yy_nxt[83] =
     {   0,
-        6,    7,    7,    8,    9,    6,   10,   11,   12,   13,
-       14,   15,   16,   11,   11,   11,   11,   11,   17,   18,
-       19,   20,   11,   11,   11,   11,   21,   11,   22,   11,
-       11,   11,   11,   11,   11,   11,   23,   24,   25,   27,
-       27,   29,   29,   31,   32,   33,   34,   29,   29,   51,
-       57,   52,   58,   59,   64,   60,   63,   62,   61,   56,
-       55,   54,   28,   28,   26,   26,   26,   26,   26,   35,
-       35,   39,   39,   53,   39,   40,   50,   40,   40,   40,
-       49,   48,   47,   46,   45,   44,   43,   42,   41,   38,
-       37,   36,   30,   65,    5,   65,   65,   65,   65,   65,
-
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65
+        6,    7,    8,    9,   10,   11,    6,   12,   13,   14,
+       15,   16,   17,   18,   19,   20,   21,   22,   12,   23,
+       24,   25,   26,   27,   29,   29,   32,   32,   32,   32,
+       35,   36,   38,   39,   43,   32,   32,   30,   30,   45,
+       31,   41,   40,   37,   45,   34,   31,   44,   28,   28,
+       28,   28,   33,   45,   33,   42,   42,    5,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45
     } ;
 
-static yyconst flex_int16_t yy_chk[135] =
+static yyconst flex_int16_t yy_chk[83] =
     {   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,    3,
-        4,    7,    7,   10,   10,   10,   10,   29,   29,   47,
-       53,   47,   53,   54,   60,   54,   59,   58,   57,   52,
-       51,   50,    3,    4,   66,   66,   66,   66,   66,   67,
-       67,   68,   68,   48,   68,   69,   46,   69,   69,   69,
-       45,   44,   43,   42,   41,   34,   33,   32,   31,   20,
-       19,   18,    8,    5,   65,   65,   65,   65,   65,   65,
-
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65
+        1,    1,    1,    1,    3,    4,    8,    8,    9,    9,
+       18,   18,   20,   20,   30,   32,   32,    3,    4,   33,
+       31,   27,   21,   19,   12,   10,    7,   30,   46,   46,
+       46,   46,   47,    5,   47,   48,   48,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45
     } ;
 
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[33] =
+    {   0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,     };
 
-extern int ce_expr_flex_debug;
-int ce_expr_flex_debug = 0;
+static yyconst flex_int16_t yy_rule_linenum[32] =
+    {   0,
+       94,   95,   96,   97,   98,   99,  100,  101,  102,  103,
+      104,  106,  107,  108,  109,  110,  111,  112,  113,  114,
+      115,  117,  119,  121,  125,  127,  129,  131,  133,  140,
+      152
+    } ;
 
 /* 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"
+#line 1 "d4_ce_scanner.ll"
 /*
  -*- 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.
+ Copyright (c) 2013 OPeNDAP, Inc.
  Author: James Gallagher <jgallagher at opendap.org>
 
  This library is free software; you can redistribute it and/or
@@ -544,76 +567,45 @@ char *ce_exprtext;
  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).
+#line 29 "d4_ce_scanner.ll"
+//#include "config.h"
 
-  jhrg 9/5/95
-*/
-#line 48 "ce_expr.lex"
-
-#include "config.h"
-
-static char rcsid[] not_used = {"$Id: ce_expr.lex 27157 2013-09-28 21:22:52Z 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); /* see das.lex */ \
-}
-
-#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);
-
-#define YY_NO_INPUT 1
-
-/* 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 617 "lex.ce_expr.cc"
+#include "D4CEScanner.h"
+
+/* typedef to make the returns for the tokens shorter */
+typedef libdap::D4CEParser::token token;
+
+/* This was added because of some notes on the net about compiler version
+   issues. I don't know if it's needed when using the C++ mode of flex. */
+#undef yywrap
+#define yywrap() 1
+
+/* define yyterminate as this instead of NULL */
+#define yyterminate() return(token::END)
+
+/* Use this if several scanners are needed. This will cause flex to
+   #define yyFlexLexer to be <prefix>FlexLexer (the yyFlexLexer is defined
+   in lex.<prefix>.cc. jhrg 8/8/13 */
+/* These two options turn on line counting - useful for error messages - 
+   and debugging, respectively. When debugging is on, it's possible to see
+   which scanner rules are used at which points in the input. */
+/* Do not output the default rule (where any unmatched input is echoed to 
+   stdout). When set, nodefault will cause the scanner to exit on an error. */
+/* noyywrap makes the scanner assume that EOF/EOS is the end of the input.
+   If this is not set, the scanner will assume there are more files to 
+   scan. */ 
+/* When set, warn prints a message when the default rule can be matched
+   but nodefault is given (among other warnings). */
+
+/* This pattern just ensures that a word does not start with '#' which
+   is the DAP2 comment character. */
+#line 83 "d4_ce_scanner.ll"
+// Code run each time a pattern is matched
+#define YY_USER_ACTION loc->columns(yyleng);
+#line 609 "lex.d4_ce.cc"
 
 #define INITIAL 0
 #define quote 1
@@ -623,55 +615,31 @@ static void store_op(int op);
  * 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.
  */
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
 #include <unistd.h>
+/* %endif */
 #endif
 
 #ifndef YY_EXTRA_TYPE
 #define YY_EXTRA_TYPE void *
 #endif
 
-static int yy_init_globals (void );
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
+/* %if-c-only Reentrant structure and macros (non-C++). */
+/* %if-reentrant */
+/* %if-c-only */
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif End reentrant structures and macros. */
+/* %if-bison-bridge */
+/* %endif */
+/* %not-for-header */
 
-int ce_exprlex_destroy (void );
+/* %ok-for-header */
 
-int ce_exprget_debug (void );
-
-void ce_exprset_debug (int debug_flag  );
-
-YY_EXTRA_TYPE ce_exprget_extra (void );
-
-void ce_exprset_extra (YY_EXTRA_TYPE user_defined  );
-
-FILE *ce_exprget_in (void );
-
-void ce_exprset_in  (FILE * in_str  );
-
-FILE *ce_exprget_out (void );
-
-void ce_exprset_out  (FILE * out_str  );
-
-int ce_exprget_leng (void );
-
-char *ce_exprget_text (void );
-
-int ce_exprget_lineno (void );
-
-void ce_exprset_lineno (int line_number  );
-
-/* 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
+/* %endif */
 
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char *,yyconst char *,int );
@@ -682,15 +650,17 @@ static int yy_flex_strlen (yyconst char * );
 #endif
 
 #ifndef YY_NO_INPUT
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
 
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
+/* %ok-for-header */
 
+/* %endif */
 #endif
 
+/* %if-c-only */
+/* %endif */
+
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
 #define YY_READ_BUF_SIZE 8192
@@ -698,10 +668,11 @@ static int input (void );
 
 /* 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 do { if (fwrite( ce_exprtext, ce_exprleng, 1, ce_exprout )) {} } while (0)
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
+/* %if-c++-only C++ definition */
+#define ECHO LexerOutput( yytext, yyleng )
+/* %endif */
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -709,34 +680,12 @@ static int input (void );
  */
 #ifndef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-		{ \
-		int c = '*'; \
-		unsigned 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); \
-			} \
-		}\
+/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\
 \
+/* %if-c++-only C++ definition \ */\
+	if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+/* %endif */
 
 #endif
 
@@ -755,23 +704,39 @@ static int input (void );
 
 /* Report a fatal error. */
 #ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+#define YY_FATAL_ERROR(msg) LexerError( msg )
+/* %endif */
 #endif
 
+/* %if-tables-serialization structures and prototypes */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* %tables-yydmap generated elements */
+/* %endif */
 /* end tables serialization structures and prototypes */
 
+/* %ok-for-header */
+
 /* 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)
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
+/* %if-c++-only C++ definition */
+#define YY_DECL int yyFlexLexer::yylex()
+/* %endif */
 #endif /* !YY_DECL */
 
-/* Code executed at the beginning of each rule, after ce_exprtext and ce_exprleng
+/* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
  */
 #ifndef YY_USER_ACTION
@@ -783,9 +748,12 @@ extern int ce_exprlex (void);
 #define YY_BREAK break;
 #endif
 
+/* %% [6.0] YY_RULE_SETUP definition goes here */
 #define YY_RULE_SETUP \
 	YY_USER_ACTION
 
+/* %not-for-header */
+
 /** The main scanner function which does all the work.
  */
 YY_DECL
@@ -794,10 +762,16 @@ YY_DECL
 	register char *yy_cp, *yy_bp;
 	register int yy_act;
     
-#line 132 "ce_expr.lex"
+/* %% [7.0] user's declarations go here */
+#line 87 "d4_ce_scanner.ll"
 
 
-#line 801 "lex.ce_expr.cc"
+
+// Code run each time yylex is called
+loc->step();
+
+
+#line 775 "lex.d4_ce.cc"
 
 	if ( !(yy_init) )
 		{
@@ -810,23 +784,32 @@ YY_DECL
 		if ( ! (yy_start) )
 			(yy_start) = 1;	/* first start state */
 
-		if ( ! ce_exprin )
-			ce_exprin = stdin;
+		if ( ! yyin )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+			yyin = & std::cin;
+/* %endif */
 
-		if ( ! ce_exprout )
-			ce_exprout = stdout;
+		if ( ! yyout )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+			yyout = & std::cout;
+/* %endif */
 
 		if ( ! YY_CURRENT_BUFFER ) {
-			ce_exprensure_buffer_stack ();
+			yyensure_buffer_stack ();
 			YY_CURRENT_BUFFER_LVALUE =
-				ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+				yy_create_buffer( yyin, YY_BUF_SIZE );
 		}
 
-		ce_expr_load_buffer_state( );
+		yy_load_buffer_state(  );
 		}
 
 	while ( 1 )		/* loops until end-of-file is reached */
 		{
+/* %% [8.0] yymore()-related code goes here */
 		(yy_more_len) = 0;
 		if ( (yy_more_flag) )
 			{
@@ -835,7 +818,7 @@ YY_DECL
 			}
 		yy_cp = (yy_c_buf_p);
 
-		/* Support of ce_exprtext. */
+		/* Support of yytext. */
 		*yy_cp = (yy_hold_char);
 
 		/* yy_bp points to the position in yy_ch_buf of the start of
@@ -843,6 +826,7 @@ YY_DECL
 		 */
 		yy_bp = yy_cp;
 
+/* %% [9.0] code to set up and find next match goes here */
 		yy_current_state = (yy_start);
 yy_match:
 		do
@@ -856,29 +840,55 @@ yy_match:
 			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 >= 66 )
+				if ( yy_current_state >= 46 )
 					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] != 95 );
+		while ( yy_current_state != 45 );
+		yy_cp = (yy_last_accepting_cpos);
+		yy_current_state = (yy_last_accepting_state);
 
 yy_find_action:
+/* %% [10.0] code to find the action number goes here */
 		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;
 
+/* %% [11.0] code for yylineno update goes here */
+
+		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+			{
+			yy_size_t yyl;
+			for ( yyl = (yy_more_len); yyl < yyleng; ++yyl )
+				if ( yytext[yyl] == '\n' )
+					   
+    yylineno++;
+;
+			}
+
 do_action:	/* This label is used only to access EOF actions. */
 
+/* %% [12.0] debug code goes here */
+		if ( yy_flex_debug )
+			{
+			if ( yy_act == 0 )
+				std::cerr << "--scanner backing up\n";
+			else if ( yy_act < 32 )
+				std::cerr << "--accepting rule at line " << yy_rule_linenum[yy_act] <<
+				         "(\"" << yytext << "\")\n";
+			else if ( yy_act == 32 )
+				std::cerr << "--accepting default rule (\"" << yytext << "\")\n";
+			else if ( yy_act == 33 )
+				std::cerr << "--(end of buffer or a NUL)\n";
+			else
+				std::cerr << "--EOF (start condition " << YY_START << ")\n";
+			}
+
 		switch ( yy_act )
 	{ /* beginning of action switch */
+/* %% [13.0] actions go here */
 			case 0: /* must back up */
 			/* undo the effects of YY_DO_BEFORE_ACTION */
 			*yy_cp = (yy_hold_char);
@@ -888,190 +898,193 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 134 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 94 "d4_ce_scanner.ll"
+return token::LBRACKET;
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 135 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 95 "d4_ce_scanner.ll"
+return token::RBRACKET;
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 136 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 96 "d4_ce_scanner.ll"
+return token::COLON;
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 137 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 97 "d4_ce_scanner.ll"
+return token::COMMA;
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 138 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 98 "d4_ce_scanner.ll"
+return token::SEMICOLON;
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 139 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 99 "d4_ce_scanner.ll"
+return token::PIPE;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 140 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 100 "d4_ce_scanner.ll"
+return token::LBRACE;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 141 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 101 "d4_ce_scanner.ll"
+return token::RBRACE;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 142 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 102 "d4_ce_scanner.ll"
+return token::GROUP_SEP;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 144 "ce_expr.lex"
-store_id(); return SCAN_WORD;
+#line 103 "d4_ce_scanner.ll"
+return token::PATH_SEP;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 146 "ce_expr.lex"
-store_op(SCAN_EQUAL); return SCAN_EQUAL;
+#line 104 "d4_ce_scanner.ll"
+return token::ASSIGN;
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 147 "ce_expr.lex"
-store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
+#line 106 "d4_ce_scanner.ll"
+return token::EQUAL;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 148 "ce_expr.lex"
-store_op(SCAN_GREATER); return SCAN_GREATER;
+#line 107 "d4_ce_scanner.ll"
+return token::NOT_EQUAL;
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 149 "ce_expr.lex"
-store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
+#line 108 "d4_ce_scanner.ll"
+return token::GREATER;
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 150 "ce_expr.lex"
-store_op(SCAN_LESS); return SCAN_LESS;
+#line 109 "d4_ce_scanner.ll"
+return token::GREATER_EQUAL;
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 151 "ce_expr.lex"
-store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
+#line 110 "d4_ce_scanner.ll"
+return token::LESS;
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 152 "ce_expr.lex"
-store_op(SCAN_REGEXP); return SCAN_REGEXP;
+#line 111 "d4_ce_scanner.ll"
+return token::LESS_EQUAL;
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 154 "ce_expr.lex"
-store_op(SCAN_STAR); return SCAN_STAR;
+#line 112 "d4_ce_scanner.ll"
+return token::REGEX_MATCH;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 156 "ce_expr.lex"
-return SCAN_HASH_BYTE;
+#line 113 "d4_ce_scanner.ll"
+return token::LESS_BBOX;
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 157 "ce_expr.lex"
-return SCAN_HASH_INT16;
+#line 114 "d4_ce_scanner.ll"
+return token::GREATER_BBOX;
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 158 "ce_expr.lex"
-return SCAN_HASH_UINT16;
+#line 115 "d4_ce_scanner.ll"
+return token::MASK;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 159 "ce_expr.lex"
-return SCAN_HASH_INT32;
+#line 117 "d4_ce_scanner.ll"
+/* ignore these */
 	YY_BREAK
 case 23:
+/* rule 23 can match eol */
 YY_RULE_SETUP
-#line 160 "ce_expr.lex"
-return SCAN_HASH_UINT32;
+#line 119 "d4_ce_scanner.ll"
+/* ignore these */
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 161 "ce_expr.lex"
-return SCAN_HASH_FLOAT32;
+#line 121 "d4_ce_scanner.ll"
+{ yylval->build<std::string>(yytext); return token::WORD; }
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 123 "d4_ce_scanner.ll"
+return token::END;
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 162 "ce_expr.lex"
-return SCAN_HASH_FLOAT64;
+#line 125 "d4_ce_scanner.ll"
+{ BEGIN(quote); yymore(); }
 	YY_BREAK
 case 26:
 /* rule 26 can match eol */
 YY_RULE_SETUP
-#line 164 "ce_expr.lex"
-
-	YY_BREAK
-case YY_STATE_EOF(INITIAL):
-#line 165 "ce_expr.lex"
-yy_init = 1; yyterminate();
+#line 127 "d4_ce_scanner.ll"
+yymore(); /* Anything that's not a double quote or a backslash */
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 167 "ce_expr.lex"
-BEGIN(quote); yymore();
+#line 129 "d4_ce_scanner.ll"
+yymore(); /* This matches the escaped double quote (\") */
 	YY_BREAK
 case 28:
-/* rule 28 can match eol */
 YY_RULE_SETUP
-#line 169 "ce_expr.lex"
-yymore(); /*"*/
+#line 131 "d4_ce_scanner.ll"
+yymore(); /* This matches an escaped escape (\\) */
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 171 "ce_expr.lex"
-yymore();
+#line 133 "d4_ce_scanner.ll"
+{
+                    BEGIN(INITIAL);
+                    if (yytext) {
+                        YY_FATAL_ERROR("Inside a string, backslash (\\) can escape a double quote or must itself be escaped (\\\\).");
+                    }
+                }
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 173 "ce_expr.lex"
+#line 140 "d4_ce_scanner.ll"
 { 
-    		  BEGIN(INITIAL); 
-              store_str();
-              return SCAN_STR;
+                /* An unescaped double quote in the 'quote' state indicates the end of the string */
+                BEGIN(INITIAL); 
+                yylval->build<std::string>(yytext); 
+                return token::STRING;
             }
 	YY_BREAK
 case YY_STATE_EOF(quote):
-#line 179 "ce_expr.lex"
+#line 147 "d4_ce_scanner.ll"
 {
                   BEGIN(INITIAL);   /* resetting the state is needed for reentrant parsers */
-                  char msg[256];
-                  sprintf(msg, "Unterminated quote\n");
-                  YY_FATAL_ERROR(msg);
+                  YY_FATAL_ERROR("Unterminated quote");
                 }
 	YY_BREAK
 case 31:
-/* rule 31 can match eol */
 YY_RULE_SETUP
-#line 186 "ce_expr.lex"
+#line 152 "d4_ce_scanner.ll"
 {
-                  if (ce_exprtext) {	/* suppress msgs about `' chars */
-                    fprintf(stderr, "Character `%c' is not", *ce_exprtext);
-                    fprintf(stderr, " allowed and has been ignored\n");
-                  }
-		        }
+        BEGIN(INITIAL);
+        if (yytext) {
+            YY_FATAL_ERROR("Characters found in the input were not recognized.");
+        }
+    }
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 192 "ce_expr.lex"
-ECHO;
+#line 158 "d4_ce_scanner.ll"
+YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 1075 "lex.ce_expr.cc"
+#line 1088 "lex.d4_ce.cc"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1086,15 +1099,15 @@ ECHO;
 			{
 			/* 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
+			 * just pointed yyin at a new source and called
+			 * yylex().  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_input_file = yyin;
 			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
 			}
 
@@ -1136,7 +1149,9 @@ ECHO;
 
 			else
 				{
-				yy_cp = (yy_c_buf_p);
+/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
+				yy_cp = (yy_last_accepting_cpos);
+				yy_current_state = (yy_last_accepting_state);
 				goto yy_find_action;
 				}
 			}
@@ -1147,11 +1162,11 @@ ECHO;
 				{
 				(yy_did_buffer_switch_on_eof) = 0;
 
-				if ( ce_exprwrap( ) )
+				if ( yywrap(  ) )
 					{
 					/* Note: because we've taken care in
 					 * yy_get_next_buffer() to have set up
-					 * ce_exprtext, we can now set up
+					 * yytext, 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
@@ -1200,7 +1215,103 @@ ECHO;
 			"fatal flex scanner internal error--no action found" );
 	} /* end of action switch */
 		} /* end of scanning one token */
-} /* end of ce_exprlex */
+} /* end of yylex */
+/* %ok-for-header */
+
+/* %if-c++-only */
+/* %not-for-header */
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout )
+{
+	yyin = arg_yyin;
+	yyout = arg_yyout;
+	yy_c_buf_p = 0;
+	yy_init = 0;
+	yy_start = 0;
+	yy_flex_debug = 0;
+	yylineno = 1;	// this will only get updated if %option yylineno
+
+	yy_did_buffer_switch_on_eof = 0;
+
+	yy_looking_for_trail_begin = 0;
+	yy_more_flag = 0;
+	yy_more_len = 0;
+	yy_more_offset = yy_prev_more_offset = 0;
+
+	yy_start_stack_ptr = yy_start_stack_depth = 0;
+	yy_start_stack = NULL;
+
+	yy_buffer_stack = 0;
+	yy_buffer_stack_top = 0;
+	yy_buffer_stack_max = 0;
+
+	yy_state_buf = 0;
+
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::~yyFlexLexer()
+{
+	delete [] yy_state_buf;
+	d4_cefree(yy_start_stack  );
+	yy_delete_buffer( YY_CURRENT_BUFFER );
+	d4_cefree(yy_buffer_stack  );
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out )
+{
+	if ( new_in )
+		{
+		yy_delete_buffer( YY_CURRENT_BUFFER );
+		yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE  ) );
+		}
+
+	if ( new_out )
+		yyout = new_out;
+}
+
+#ifdef YY_INTERACTIVE
+size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ )
+#else
+size_t yyFlexLexer::LexerInput( char* buf, size_t max_size )
+#endif
+{
+	if ( yyin->eof() || yyin->fail() )
+		return 0;
+
+#ifdef YY_INTERACTIVE
+	yyin->get( buf[0] );
+
+	if ( yyin->eof() )
+		return 0;
+
+	if ( yyin->bad() )
+		return -1;
+
+	return 1;
+
+#else
+	(void) yyin->read( buf, max_size );
+
+	if ( yyin->bad() )
+		return -1;
+	else
+		return yyin->gcount();
+#endif
+}
+
+void yyFlexLexer::LexerOutput( const char* buf, size_t size )
+{
+	(void) yyout->write( buf, size );
+}
+/* %ok-for-header */
+
+/* %endif */
 
 /* yy_get_next_buffer - try to read in a new buffer
  *
@@ -1209,7 +1320,11 @@ ECHO;
  *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  *	EOB_ACT_END_OF_FILE - end of file
  */
-static int yy_get_next_buffer (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+int yyFlexLexer::yy_get_next_buffer()
+/* %endif */
 {
     	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
 	register char *source = (yytext_ptr);
@@ -1255,7 +1370,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1269,7 +1384,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1278,7 +1393,7 @@ static int yy_get_next_buffer (void)
 
 				b->yy_ch_buf = (char *)
 					/* Include room in for 2 EOB chars. */
-					ce_exprrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+					d4_cerealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
 				}
 			else
 				/* Can't grow it, we don't own it. */
@@ -1300,7 +1415,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1310,7 +1425,7 @@ static int yy_get_next_buffer (void)
 		if ( number_to_move == YY_MORE_ADJ )
 			{
 			ret_val = EOB_ACT_END_OF_FILE;
-			ce_exprrestart(ce_exprin  );
+			yyrestart( yyin  );
 			}
 
 		else
@@ -1327,7 +1442,7 @@ static int yy_get_next_buffer (void)
 	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ce_exprrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) d4_cerealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
 	}
@@ -1343,15 +1458,23 @@ static int yy_get_next_buffer (void)
 
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
-    static yy_state_type yy_get_previous_state (void)
+/* %if-c-only */
+/* %not-for-header */
+
+/* %endif */
+/* %if-c++-only */
+    yy_state_type yyFlexLexer::yy_get_previous_state()
+/* %endif */
 {
 	register yy_state_type yy_current_state;
 	register char *yy_cp;
     
+/* %% [15.0] code to get the start state into yy_current_state goes here */
 	yy_current_state = (yy_start);
 
 	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
 		{
+/* %% [16.0] code to find the next state goes here */
 		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
 		if ( yy_accept[yy_current_state] )
 			{
@@ -1361,7 +1484,7 @@ static int yy_get_next_buffer (void)
 		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 >= 66 )
+			if ( yy_current_state >= 46 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1375,10 +1498,15 @@ static int yy_get_next_buffer (void)
  * synopsis
  *	next_state = yy_try_NUL_trans( current_state );
  */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state )
+/* %endif */
 {
 	register int yy_is_jam;
-    	register char *yy_cp = (yy_c_buf_p);
+    /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */
+	register char *yy_cp = (yy_c_buf_p);
 
 	register YY_CHAR yy_c = 1;
 	if ( yy_accept[yy_current_state] )
@@ -1389,22 +1517,69 @@ static int yy_get_next_buffer (void)
 	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 >= 66 )
+		if ( yy_current_state >= 46 )
 			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 == 65);
+	yy_is_jam = (yy_current_state == 45);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
 
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yyunput( int c, register char* yy_bp)
+/* %endif */
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up yytext */
+	*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 yy_size_t 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;
 
+/* %% [18.0] update yylineno here */
+
+    if ( c == '\n' ){
+        --yylineno;
+    }
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+/* %if-c-only */
+/* %endif */
+
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    int yyFlexLexer::yyinput()
+/* %endif */
 {
 	int c;
     
@@ -1422,7 +1597,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1439,14 +1614,14 @@ static int yy_get_next_buffer (void)
 					 */
 
 					/* Reset buffer status. */
-					ce_exprrestart(ce_exprin );
+					yyrestart( yyin );
 
 					/*FALLTHROUGH*/
 
 				case EOB_ACT_END_OF_FILE:
 					{
-					if ( ce_exprwrap( ) )
-						return EOF;
+					if ( yywrap(  ) )
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1465,44 +1640,59 @@ static int yy_get_next_buffer (void)
 		}
 
 	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve ce_exprtext */
+	*(yy_c_buf_p) = '\0';	/* preserve yytext */
 	(yy_hold_char) = *++(yy_c_buf_p);
 
+/* %% [19.0] update BOL and yylineno */
+	if ( c == '\n' )
+		   
+    yylineno++;
+;
+
 	return c;
 }
-#endif	/* ifndef YY_NO_INPUT */
+/* %if-c-only */
+/* %endif */
 
 /** 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-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yyrestart( std::istream* input_file )
+/* %endif */
 {
     
 	if ( ! YY_CURRENT_BUFFER ){
-        ce_exprensure_buffer_stack ();
+        yyensure_buffer_stack ();
 		YY_CURRENT_BUFFER_LVALUE =
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+            yy_create_buffer( yyin, YY_BUF_SIZE );
 	}
 
-	ce_expr_init_buffer(YY_CURRENT_BUFFER,input_file );
-	ce_expr_load_buffer_state( );
+	yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+	yy_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 )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+/* %endif */
 {
     
 	/* TODO. We should be able to replace this entire function body
 	 * with
-	 *		ce_exprpop_buffer_state();
-	 *		ce_exprpush_buffer_state(new_buffer);
+	 *		yypop_buffer_state();
+	 *		yypush_buffer_state(new_buffer);
      */
-	ce_exprensure_buffer_stack ();
+	yyensure_buffer_stack ();
 	if ( YY_CURRENT_BUFFER == new_buffer )
 		return;
 
@@ -1515,21 +1705,25 @@ static int yy_get_next_buffer (void)
 		}
 
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	ce_expr_load_buffer_state( );
+	yy_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
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() 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)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_load_buffer_state()
+/* %endif */
 {
     	(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;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
 	(yy_hold_char) = *(yy_c_buf_p);
 }
 
@@ -1539,35 +1733,43 @@ static void ce_expr_load_buffer_state  (void)
  * 
  * @return the allocated buffer state.
  */
-    YY_BUFFER_STATE ce_expr_create_buffer  (FILE * file, int  size )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size )
+/* %endif */
 {
 	YY_BUFFER_STATE b;
     
-	b = (YY_BUFFER_STATE) ce_expralloc(sizeof( struct yy_buffer_state )  );
+	b = (YY_BUFFER_STATE) d4_cealloc(sizeof( struct yy_buffer_state )  );
 	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_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  );
+	b->yy_ch_buf = (char *) d4_cealloc(b->yy_buf_size + 2  );
 	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
 	b->yy_is_our_buffer = 1;
 
-	ce_expr_init_buffer(b,file );
+	yy_init_buffer( b, file );
 
 	return b;
 }
 
 /** Destroy the buffer.
- * @param b a buffer created with ce_expr_create_buffer()
+ * @param b a buffer created with yy_create_buffer()
  * 
  */
-    void ce_expr_delete_buffer (YY_BUFFER_STATE  b )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b )
+/* %endif */
 {
     
 	if ( ! b )
@@ -1577,31 +1779,40 @@ static void ce_expr_load_buffer_state  (void)
 		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
 
 	if ( b->yy_is_our_buffer )
-		ce_exprfree((void *) b->yy_ch_buf  );
+		d4_cefree((void *) b->yy_ch_buf  );
 
-	ce_exprfree((void *) b  );
+	d4_cefree((void *) b  );
 }
 
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
+/* %if-c-only */
+/* %endif */
+
+/* %if-c++-only */
+
+extern "C" int isatty (int );
+
+/* %endif */
+
 /* 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.
+ * such as during a yyrestart() or at EOF.
  */
-    static void ce_expr_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file )
+/* %endif */
 
 {
 	int oerrno = errno;
     
-	ce_expr_flush_buffer(b );
+	yy_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.
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
      * In that case, we don't want to reset the lineno or column.
      */
     if (b != YY_CURRENT_BUFFER){
@@ -1609,8 +1820,11 @@ extern int isatty (int );
         b->yy_bs_column = 0;
     }
 
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+	b->yy_is_interactive = 0;
+/* %endif */
 	errno = oerrno;
 }
 
@@ -1618,7 +1832,11 @@ extern int isatty (int );
  * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
  * 
  */
-    void ce_expr_flush_buffer (YY_BUFFER_STATE  b )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b )
+/* %endif */
 {
     	if ( ! b )
 		return;
@@ -1638,23 +1856,28 @@ extern int isatty (int );
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
 	if ( b == YY_CURRENT_BUFFER )
-		ce_expr_load_buffer_state( );
+		yy_load_buffer_state(  );
 }
 
+/* %if-c-or-c++ */
 /** 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-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer)
+/* %endif */
 {
     	if (new_buffer == NULL)
 		return;
 
-	ce_exprensure_buffer_stack();
+	yyensure_buffer_stack();
 
-	/* This block is copied from ce_expr_switch_to_buffer. */
+	/* This block is copied from yy_switch_to_buffer. */
 	if ( YY_CURRENT_BUFFER )
 		{
 		/* Flush out information for old buffer. */
@@ -1668,37 +1891,49 @@ void ce_exprpush_buffer_state (YY_BUFFER_STATE new_buffer )
 		(yy_buffer_stack_top)++;
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
 
-	/* copied from ce_expr_switch_to_buffer. */
-	ce_expr_load_buffer_state( );
+	/* copied from yy_switch_to_buffer. */
+	yy_load_buffer_state(  );
 	(yy_did_buffer_switch_on_eof) = 1;
 }
+/* %endif */
 
+/* %if-c-or-c++ */
 /** Removes and deletes the top of the stack, if present.
  *  The next element becomes the new top.
  *  
  */
-void ce_exprpop_buffer_state (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yypop_buffer_state (void)
+/* %endif */
 {
     	if (!YY_CURRENT_BUFFER)
 		return;
 
-	ce_expr_delete_buffer(YY_CURRENT_BUFFER );
+	yy_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_load_buffer_state(  );
 		(yy_did_buffer_switch_on_eof) = 1;
 	}
 }
+/* %endif */
 
+/* %if-c-or-c++ */
 /* Allocates the stack if it does not exist.
  *  Guarantees space for at least one push.
  */
-static void ce_exprensure_buffer_stack (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yyensure_buffer_stack(void)
+/* %endif */
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1707,11 +1942,11 @@ static void ce_exprensure_buffer_stack (void)
 		 * immediate realloc on the next call.
          */
 		num_to_alloc = 1;
-		(yy_buffer_stack) = (struct yy_buffer_state**)ce_expralloc
+		(yy_buffer_stack) = (struct yy_buffer_state**)d4_cealloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ce_exprensure_buffer_stack()" );
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 								  
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 				
@@ -1726,114 +1961,91 @@ static void ce_exprensure_buffer_stack (void)
 		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) = (struct yy_buffer_state**)d4_cerealloc
 								((yy_buffer_stack),
 								num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ce_exprensure_buffer_stack()" );
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 
 		/* 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;
 	}
 }
+/* %endif */
 
-/** 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;
+/* %if-c-only */
+/* %endif */
 
-	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()" );
+/* %if-c-only */
+/* %endif */
 
-	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;
+/* %if-c-only */
+/* %endif */
 
-	ce_expr_switch_to_buffer(b  );
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_push_state( int new_state )
+/* %endif */
+{
+    	if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) )
+		{
+		yy_size_t new_size;
 
-	return b;
-}
+		(yy_start_stack_depth) += YY_START_STACK_INCR;
+		new_size = (yy_start_stack_depth) * sizeof( int );
 
-/** 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 yystr 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) );
-}
+		if ( ! (yy_start_stack) )
+			(yy_start_stack) = (int *) d4_cealloc(new_size  );
 
-/** 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()" );
+		else
+			(yy_start_stack) = (int *) d4_cerealloc((void *) (yy_start_stack),new_size  );
 
-	for ( i = 0; i < _yybytes_len; ++i )
-		buf[i] = yybytes[i];
+		if ( ! (yy_start_stack) )
+			YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+		}
 
-	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+	(yy_start_stack)[(yy_start_stack_ptr)++] = YY_START;
 
-	b = ce_expr_scan_buffer(buf,n );
-	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in ce_expr_scan_bytes()" );
+	BEGIN(new_state);
+}
 
-	/* It's okay to grow etc. this buffer, and we should throw it
-	 * away when we're done.
-	 */
-	b->yy_is_our_buffer = 1;
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_pop_state()
+/* %endif */
+{
+    	if ( --(yy_start_stack_ptr) < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
 
-	return b;
+	BEGIN((yy_start_stack)[(yy_start_stack_ptr)]);
+}
+
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    int yyFlexLexer::yy_top_state()
+/* %endif */
+{
+    	return (yy_start_stack)[(yy_start_stack_ptr) - 1];
 }
 
 #ifndef YY_EXIT_FAILURE
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yy_fatal_error (yyconst char* msg )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::LexerError( yyconst char msg[] )
 {
-    	(void) fprintf( stderr, "%s\n", msg );
+    	std::cerr << msg << std::endl;
 	exit( YY_EXIT_FAILURE );
 }
+/* %endif */
 
 /* Redefine yyless() so it works in section 3 code. */
 
@@ -1841,146 +2053,38 @@ static void yy_fatal_error (yyconst char* msg )
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ce_exprtext. */ \
+		/* Undo effects of setting up yytext. */ \
         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; \
+		yytext[yyleng] = (yy_hold_char); \
+		(yy_c_buf_p) = yytext + yyless_macro_arg; \
 		(yy_hold_char) = *(yy_c_buf_p); \
 		*(yy_c_buf_p) = '\0'; \
-		ce_exprleng = yyless_macro_arg; \
+		yyleng = 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;
-}
+/* %if-c-only */
+/* %if-reentrant */
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif */
 
-/** Get the length of the current token.
- * 
- */
-int ce_exprget_leng  (void)
-{
-        return ce_exprleng;
-}
+/* %if-reentrant */
+/* %if-bison-bridge */
+/* %endif */
+/* %endif if-c-only */
 
-/** Get the current token.
- * 
- */
-
-char *ce_exprget_text  (void)
-{
-        return ce_exprtext;
-}
+/* %if-c-only */
+/* %endif */
 
-/** 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;
-}
+/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
+/* %if-reentrant */
+/* %endif */
+/* %endif */
 
 /*
  * Internal utility routines.
@@ -2006,12 +2110,12 @@ static int yy_flex_strlen (yyconst char * s )
 }
 #endif
 
-void *ce_expralloc (yy_size_t  size )
+void *d4_cealloc (yy_size_t  size )
 {
 	return (void *) malloc( size );
 }
 
-void *ce_exprrealloc  (void * ptr, yy_size_t  size )
+void *d4_cerealloc  (void * ptr, yy_size_t  size )
 {
 	/* The cast to (char *) in the following accommodates both
 	 * implementations that use char* generic pointers, and those
@@ -2023,69 +2127,19 @@ void *ce_exprrealloc  (void * ptr, yy_size_t  size )
 	return (void *) realloc( (char *) ptr, size );
 }
 
-void ce_exprfree (void * ptr )
+void d4_cefree (void * ptr )
 {
-	free( (char *) ptr );	/* see ce_exprrealloc() for (char *) cast */
+	free( (char *) ptr );	/* see d4_cerealloc() for (char *) cast */
 }
 
+/* %if-tables-serialization definitions */
+/* %define-yytables   The name for this specific scanner's tables. */
 #define YYTABLES_NAME "yytables"
+/* %endif */
 
-#line 192 "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, ce_exprtext, ID_MAX-1);
-    ce_exprlval.id[ID_MAX-1] = '\0';
-}
+/* %ok-for-header */
 
-static void
-store_str()
-{
-    // transform %20 to a space. 7/11/2001 jhrg
-    string *s = new string(ce_exprtext); // move all calls of www2id into the parser. jhrg 7/5/13 www2id(string(ce_exprtext)));
-
-    if (*s->begin() == '\"' && *(s->end()-1) == '\"') {
-	s->erase(s->begin());
-	s->erase(s->end()-1);
-    }
+#line 158 "d4_ce_scanner.ll"
 
-    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.ce_expr.cc b/d4_ce/gen_grammar_sources/lex.d4_function.cc.tmp
similarity index 53%
copy from lex.ce_expr.cc
copy to d4_ce/gen_grammar_sources/lex.d4_function.cc.tmp
index 8d2a9d6..3f57dbc 100644
--- a/lex.ce_expr.cc
+++ b/d4_ce/gen_grammar_sources/lex.d4_function.cc.tmp
@@ -1,29 +1,17 @@
-#line 2 "lex.ce_expr.cc"
 
-#line 4 "lex.ce_expr.cc"
+#line 3 "lex.d4_function.cc"
 
 #define  YY_INT_ALIGNED short int
 
 /* A lexical scanner generated by flex */
 
-#define yy_create_buffer ce_expr_create_buffer
-#define yy_delete_buffer ce_expr_delete_buffer
-#define yy_flex_debug ce_expr_flex_debug
-#define yy_init_buffer ce_expr_init_buffer
-#define yy_flush_buffer ce_expr_flush_buffer
-#define yy_load_buffer_state ce_expr_load_buffer_state
-#define yy_switch_to_buffer ce_expr_switch_to_buffer
-#define yyin ce_exprin
-#define yyleng ce_exprleng
-#define yylex ce_exprlex
-#define yylineno ce_exprlineno
-#define yyout ce_exprout
-#define yyrestart ce_exprrestart
-#define yytext ce_exprtext
-#define yywrap ce_exprwrap
-#define yyalloc ce_expralloc
-#define yyrealloc ce_exprrealloc
-#define yyfree ce_exprfree
+/* %not-for-header */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+/* %endif */
+/* %endif */
+/* %ok-for-header */
 
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
@@ -33,16 +21,33 @@
 #define FLEX_BETA
 #endif
 
+/* %if-c++-only */
+    /* The c++ scanner is a mess. The FlexLexer.h header file relies on the
+     * following macro. This is required in order to pass the c++-multiple-scanners
+     * test in the regression suite. We get reports that it breaks inheritance.
+     * We will address this in a future release of flex, or omit the C++ scanner
+     * altogether.
+     */
+    #define yyFlexLexer d4_functionFlexLexer
+/* %endif */
+
+/* %if-c-only */
+/* %endif */
+
+/* %if-c-only */
+/* %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>
+/* %if-c-only */
+/* %endif */
 
+/* %if-tables-serialization */
+/* %endif */
 /* end standard C headers. */
 
+/* %if-c-or-c++ */
 /* flex integer type definitions */
 
 #ifndef FLEXINT_H
@@ -66,6 +71,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -106,6 +112,17 @@ typedef unsigned int flex_uint32_t;
 
 #endif /* ! FLEXINT_H */
 
+/* %endif */
+
+/* %if-c++-only */
+/* begin standard C++ headers. */
+#include <iostream> 
+#include <errno.h>
+#include <cstdlib>
+#include <cstring>
+/* end standard C++ headers. */
+/* %endif */
+
 #ifdef __cplusplus
 
 /* The "const" storage-class-modifier is valid. */
@@ -127,8 +144,13 @@ typedef unsigned int flex_uint32_t;
 #define yyconst
 #endif
 
+/* %not-for-header */
+
 /* Returned upon end-of-file. */
 #define YY_NULL 0
+/* %ok-for-header */
+
+/* %not-for-header */
 
 /* Promotes a possibly negative, possibly signed char to an unsigned
  * integer for use as an array index.  If the signed char is negative,
@@ -136,6 +158,14 @@ typedef unsigned int flex_uint32_t;
  * double cast.
  */
 #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+/* %ok-for-header */
+
+/* %if-reentrant */
+/* %endif */
+
+/* %if-not-reentrant */
+
+/* %endif */
 
 /* 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
@@ -154,7 +184,7 @@ typedef unsigned int flex_uint32_t;
 #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_NEW_FILE yyrestart( yyin  )
 
 #define YY_END_OF_BUFFER_CHAR 0
 
@@ -172,42 +202,65 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int ce_exprleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+/* %if-not-reentrant */
+extern yy_size_t yyleng;
+/* %endif */
 
-extern FILE *ce_exprin, *ce_exprout;
+/* %if-c-only */
+/* %if-not-reentrant */
+/* %endif */
+/* %endif */
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
 
-    #define YY_LESS_LINENO(n)
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+     *       access to the local variable yy_act. Since yyless() is a macro, it would break
+     *       existing scanners that call yyless() from OUTSIDE yylex. 
+     *       One obvious solution it to make yy_act a global. I tried that, and saw
+     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                yy_size_t yyl;\
+                for ( yyl = n; yyl < yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
     
 /* Return all but the first "n" matched characters back to the input stream. */
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ce_exprtext. */ \
+		/* Undo effects of setting up yytext. */ \
         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 */ \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
 		} \
 	while ( 0 )
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
 	{
-	FILE *yy_input_file;
+/* %if-c-only */
+/* %endif */
+
+/* %if-c++-only */
+	std::istream* yy_input_file;
+/* %endif */
 
 	char *yy_ch_buf;		/* input buffer */
 	char *yy_buf_pos;		/* current position in input buffer */
@@ -220,7 +273,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t 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
@@ -260,18 +313,22 @@ struct yy_buffer_state
 	 * 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.
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin 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. */
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+/* %if-not-reentrant */
+/* %endif */
+/* %ok-for-header */
+
+/* %endif */
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
@@ -288,51 +345,27 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
  */
 #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;
+/* %if-c-only Standard (non-C++) definition */
+/* %if-not-reentrant */
+/* %not-for-header */
 
-/* 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 */
+/* %ok-for-header */
 
-/* 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  );
+/* %endif */
+/* %endif */
 
-void *ce_expralloc (yy_size_t  );
-void *ce_exprrealloc (void *,yy_size_t  );
-void ce_exprfree (void *  );
+void *d4_functionalloc (yy_size_t  );
+void *d4_functionrealloc (void *,yy_size_t  );
+void d4_functionfree (void *  );
 
-#define yy_new_buffer ce_expr_create_buffer
+#define yy_new_buffer yy_create_buffer
 
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
-        ce_exprensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
@@ -340,51 +373,55 @@ void ce_exprfree (void *  );
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
-        ce_exprensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
 
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
+/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
 /* Begin user sect3 */
-
-#define ce_exprwrap(n) 1
 #define YY_SKIP_YYWRAP
 
-typedef unsigned char YY_CHAR;
+#define FLEX_DEBUG
 
-FILE *ce_exprin = (FILE *) 0, *ce_exprout = (FILE *) 0;
+typedef unsigned char YY_CHAR;
 
-typedef int yy_state_type;
+#define yytext_ptr yytext
 
-extern int ce_exprlineno;
+#include <FlexLexer.h>
 
-int ce_exprlineno = 1;
+int yyFlexLexer::yywrap() { return 1; }
+int yyFlexLexer::yylex()
+	{
+	LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" );
+	return 0;
+	}
 
-extern char *ce_exprtext;
-#define yytext_ptr ce_exprtext
+#define YY_DECL int D4FunctionScanner::yylex()
 
-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[]  );
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
 
 /* Done after the current pattern has been matched and before the
- * corresponding action - sets up ce_exprtext.
+ * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\
 	(yytext_ptr) -= (yy_more_len); \
-	ce_exprleng = (size_t) (yy_cp - (yytext_ptr)); \
+	yyleng = (yy_size_t) (yy_cp - (yytext_ptr)); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
+/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
 	(yy_c_buf_p) = yy_cp;
 
-#define YY_NUM_RULES 32
-#define YY_END_OF_BUFFER 33
+/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
+#define YY_NUM_RULES 29
+#define YY_END_OF_BUFFER 30
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -392,33 +429,33 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[66] =
+static yyconst flex_int16_t yy_accept[64] =
     {   0,
-        0,    0,   28,   28,   33,   31,   26,   31,   27,   31,
-       10,    5,    6,    7,   18,    4,    3,   15,   11,   13,
-        1,    2,    8,    9,   32,   28,   30,   32,   26,   12,
-        0,    0,    0,    0,   10,   16,   17,   14,   28,   29,
-        0,    0,    0,    0,    0,    0,    0,    0,   19,    0,
-        0,    0,    0,    0,   20,   22,    0,    0,    0,    0,
-       21,   23,   24,   25,    0
+        0,    0,   23,   23,   30,   28,   19,   20,   20,   21,
+       22,   28,    4,    5,    1,    7,    6,    3,    2,   23,
+       27,   26,   19,   20,   21,    0,    0,    0,    0,   23,
+       24,   25,    0,    0,    0,    0,    0,    0,    0,    0,
+        8,    0,    0,    0,    0,   10,    0,    0,   12,   14,
+       16,    0,    0,    0,    9,    0,    0,   11,   13,   15,
+       17,   18,    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,    4,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    4,    5,    6,    7,    8,    9,    1,   10,
-       11,   12,    8,   13,    8,    8,    8,    8,   14,   15,
-       16,   17,    8,   18,    8,    8,    8,   19,    1,   20,
-       21,   22,    1,    1,    8,   23,    8,    8,    8,   24,
-        8,    8,   25,    8,    8,    8,    8,    8,    8,    8,
-        8,    8,    8,    8,   26,    8,    8,    8,    8,    8,
-       27,   28,   29,    1,    8,    1,   30,    8,    8,    8,
-
-       31,    8,    8,    8,    8,    8,    8,   32,    8,   33,
-       34,    8,    8,    8,    8,   35,    8,    8,    8,    8,
-       36,    8,   37,    1,   38,   39,    1,    1,    1,    1,
+        1,    2,    5,    6,    5,    7,    5,    1,    1,    8,
+        9,    5,    5,   10,    5,   11,   12,    5,   13,   14,
+       15,   16,    5,   17,    5,   18,    5,   19,   20,    1,
+        1,    1,    1,    5,    5,   21,    5,    5,    5,   22,
+        5,    5,   23,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,   24,    5,    5,    5,    5,    5,
+        1,   25,    1,    1,    5,    1,   26,    5,    5,    5,
+
+       27,    5,    5,    5,    5,    5,    5,   28,    5,   29,
+       30,    5,    5,    5,    5,   31,    5,    5,    5,    5,
+       32,    5,    1,    1,    1,    5,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -435,98 +472,100 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[40] =
+static yyconst flex_int32_t yy_meta[33] =
     {   0,
-        1,    1,    2,    1,    3,    4,    1,    4,    1,    1,
-        1,    1,    1,    4,    4,    4,    4,    4,    1,    1,
-        1,    1,    4,    4,    4,    4,    1,    5,    1,    4,
-        4,    4,    4,    4,    4,    4,    1,    1,    1
+        1,    1,    1,    1,    2,    3,    1,    1,    1,    1,
+        1,    1,    2,    2,    2,    2,    2,    2,    1,    1,
+        2,    2,    2,    2,    4,    2,    2,    2,    2,    2,
+        2,    2
     } ;
 
-static yyconst flex_int16_t yy_base[70] =
+static yyconst flex_int16_t yy_base[67] =
     {   0,
-        0,    0,   35,   36,   94,   95,   40,   72,   95,   21,
-        0,   95,   95,   95,   95,   95,   95,   71,   52,   69,
-       95,   95,   95,   95,   95,    0,   95,    0,   46,   95,
-       53,   56,   54,   61,    0,   95,   95,   95,    0,   95,
-       50,   50,   48,   49,   50,   47,   36,   39,   95,   27,
-       43,   45,   37,   38,   95,   95,   41,   43,   42,   38,
-       95,   95,   95,   95,   95,   64,   66,   71,   75
+        0,    0,   27,   28,   89,   90,   86,   32,   34,    0,
+       90,   18,   90,   90,   90,   90,   90,   90,   90,    0,
+       90,   37,   85,   41,    0,   54,   57,   55,   60,    0,
+       90,   90,   51,   51,   49,   50,   51,   51,   33,   45,
+       90,   44,   57,   59,   56,   90,   41,   32,   90,   90,
+       90,   51,   47,   44,   90,   43,   39,   90,   90,   90,
+       90,   90,   90,   62,   65,   69
     } ;
 
-static yyconst flex_int16_t yy_def[70] =
+static yyconst flex_int16_t yy_def[67] =
     {   0,
-       65,    1,   66,   66,   65,   65,   65,   65,   65,   65,
-       67,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   68,   65,   69,   65,   65,
-       65,   65,   65,   65,   67,   65,   65,   65,   68,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,    0,   65,   65,   65,   65
+       63,    1,   64,   64,   63,   63,   63,   63,   63,   65,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   66,
+       63,   63,   63,   63,   65,   63,   63,   63,   63,   66,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,    0,   63,   63,   63
     } ;
 
-static yyconst flex_int16_t yy_nxt[135] =
+static yyconst flex_int16_t yy_nxt[123] =
     {   0,
-        6,    7,    7,    8,    9,    6,   10,   11,   12,   13,
-       14,   15,   16,   11,   11,   11,   11,   11,   17,   18,
-       19,   20,   11,   11,   11,   11,   21,   11,   22,   11,
-       11,   11,   11,   11,   11,   11,   23,   24,   25,   27,
-       27,   29,   29,   31,   32,   33,   34,   29,   29,   51,
-       57,   52,   58,   59,   64,   60,   63,   62,   61,   56,
-       55,   54,   28,   28,   26,   26,   26,   26,   26,   35,
-       35,   39,   39,   53,   39,   40,   50,   40,   40,   40,
-       49,   48,   47,   46,   45,   44,   43,   42,   41,   38,
-       37,   36,   30,   65,    5,   65,   65,   65,   65,   65,
-
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65
+        6,    7,    8,    9,   10,   11,   12,   13,   14,   15,
+       16,   17,   10,   10,   10,   10,   10,   10,   18,   19,
+       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
+       10,   10,   21,   21,   24,   24,   24,   24,   26,   27,
+       28,   29,   31,   24,   24,   43,   56,   44,   57,   45,
+       46,   22,   22,   52,   62,   53,   61,   54,   55,   60,
+       59,   32,   20,   20,   20,   20,   25,   58,   25,   30,
+       30,   51,   50,   49,   48,   47,   42,   41,   40,   39,
+       38,   37,   36,   35,   34,   33,   23,   23,   63,    5,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63
     } ;
 
-static yyconst flex_int16_t yy_chk[135] =
+static yyconst flex_int16_t yy_chk[123] =
     {   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,    3,
-        4,    7,    7,   10,   10,   10,   10,   29,   29,   47,
-       53,   47,   53,   54,   60,   54,   59,   58,   57,   52,
-       51,   50,    3,    4,   66,   66,   66,   66,   66,   67,
-       67,   68,   68,   48,   68,   69,   46,   69,   69,   69,
-       45,   44,   43,   42,   41,   34,   33,   32,   31,   20,
-       19,   18,    8,    5,   65,   65,   65,   65,   65,   65,
-
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65
+        1,    1,    3,    4,    8,    8,    9,    9,   12,   12,
+       12,   12,   22,   24,   24,   39,   48,   39,   48,   39,
+       39,    3,    4,   47,   57,   47,   56,   47,   47,   54,
+       53,   22,   64,   64,   64,   64,   65,   52,   65,   66,
+       66,   45,   44,   43,   42,   40,   38,   37,   36,   35,
+       34,   33,   29,   28,   27,   26,   23,    7,    5,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63
     } ;
 
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[30] =
+    {   0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1, 0, 0, 1, 0, 0, 0, 0, 0, 0,     };
 
-extern int ce_expr_flex_debug;
-int ce_expr_flex_debug = 0;
+static yyconst flex_int16_t yy_rule_linenum[29] =
+    {   0,
+      121,  122,  123,  125,  126,  128,  129,  131,  132,  133,
+      134,  135,  136,  137,  138,  139,  140,  141,  143,  145,
+      147,  151,  153,  155,  157,  159,  166,  178
+    } ;
 
 /* 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"
+#line 1 "d4_function_scanner.ll"
 /*
  -*- 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.
+ Copyright (c) 2014 OPeNDAP, Inc.
  Author: James Gallagher <jgallagher at opendap.org>
 
  This library is free software; you can redistribute it and/or
@@ -544,76 +583,71 @@ char *ce_exprtext;
  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"
+#line 29 "d4_function_scanner.ll"
 
-#include "config.h"
+//#include "config.h"
 
-static char rcsid[] not_used = {"$Id: ce_expr.lex 27157 2013-09-28 21:22:52Z 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); /* see das.lex */ \
-}
-
-#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);
-
-#define YY_NO_INPUT 1
-
-/* 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
+#include "D4FunctionScanner.h"
+
+/* typedef to make the returns for the tokens shorter */
+
+/* NB: It would be best to use the same scanner (and maybe parser) for
+   both the D4 CE and Function parameters, but for the initial version 
+   far less complexity is require by the Function expression scanner
+   (since the initial version will just support variables, constants, 
+   functions and the $<type> array special form) and not function arguments
+   that are general expressions (like array slicing and/or filters).
+   
+   This comment is here because this is the first place where there is 
+   coupling between the CE parser and its scanner. I'm not sure, however,
+   if one string can be parsed by two parsers if they are using two scanners,
+   so extending the Function parser to allow function args to be any CE 
+   clause may mean some more serious work with the parsers.
+   
+   jhrg 3/10/14 */
+typedef libdap::D4FunctionParser::token token;
+
+/* This was added because of some notes on the net about compiler version
+   issues. I don't know if it's needed when using the C++ mode of flex. */
+#undef yywrap
+#define yywrap() 1
+
+/* define yyterminate as this instead of NULL */
+#define yyterminate() return(token::END)
+
+/* Use this if several scanners are needed. This will cause flex to
+   #define yyFlexLexer to be <prefix>FlexLexer (the yyFlexLexer is defined
+   in lex.<prefix>.cc. jhrg 8/8/13 */
+/* These two options turn on line counting - useful for error messages - 
+   and debugging, respectively. When debugging is on, it's possible to see
+   which scanner rules are used at which points in the input. */
+/* Do not output the default rule (where any unmatched input is echoed to 
+   stdout). When set, nodefault will cause the scanner to exit on an error. */
+/* noyywrap makes the scanner assume that EOF/EOS is the end of the input.
+   If this is not set, the scanner will assume there are more files to 
+   scan. */ 
+/* When set, warn prints a message when the default rule can be matched
+   but nodefault is given (among other warnings). */
+
+/* This pattern is slightly different from the one used by the CE scanner
+   because it allows a WORD to start with a '#' so that the #<type> 
+   array constant syntax can be used in functions. Otherwise, a WORD must
+   be able to contain this hideous mix of characters because a variable 
+   can. jhrg 3/10/14 */
+/* I added these tokens because floating point values may contain dots and
+   added a '.' to WORD will break the parsing of paths (or make for some 
+   fairly obscure code - where $Float32() takes tokens that match 'path'.
+   Since we have a separate scanner for the function expressions, might as
+   well add a FLOAT token... jhg 3/17/14 
+FLOAT   [-+eE.0-9][-+eE.0-9]*
 */
-#line 617 "lex.ce_expr.cc"
+#line 110 "d4_function_scanner.ll"
+// Code run each time a pattern is matched
+#define YY_USER_ACTION loc->columns(yyleng);
+#line 651 "lex.d4_function.cc"
 
 #define INITIAL 0
 #define quote 1
@@ -623,55 +657,31 @@ static void store_op(int op);
  * 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.
  */
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
 #include <unistd.h>
+/* %endif */
 #endif
 
 #ifndef YY_EXTRA_TYPE
 #define YY_EXTRA_TYPE void *
 #endif
 
-static int yy_init_globals (void );
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int ce_exprlex_destroy (void );
-
-int ce_exprget_debug (void );
+/* %if-c-only Reentrant structure and macros (non-C++). */
+/* %if-reentrant */
+/* %if-c-only */
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif End reentrant structures and macros. */
+/* %if-bison-bridge */
+/* %endif */
+/* %not-for-header */
 
-void ce_exprset_debug (int debug_flag  );
+/* %ok-for-header */
 
-YY_EXTRA_TYPE ce_exprget_extra (void );
-
-void ce_exprset_extra (YY_EXTRA_TYPE user_defined  );
-
-FILE *ce_exprget_in (void );
-
-void ce_exprset_in  (FILE * in_str  );
-
-FILE *ce_exprget_out (void );
-
-void ce_exprset_out  (FILE * out_str  );
-
-int ce_exprget_leng (void );
-
-char *ce_exprget_text (void );
-
-int ce_exprget_lineno (void );
-
-void ce_exprset_lineno (int line_number  );
-
-/* 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
+/* %endif */
 
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char *,yyconst char *,int );
@@ -682,15 +692,17 @@ static int yy_flex_strlen (yyconst char * );
 #endif
 
 #ifndef YY_NO_INPUT
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
 
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
+/* %ok-for-header */
 
+/* %endif */
 #endif
 
+/* %if-c-only */
+/* %endif */
+
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
 #define YY_READ_BUF_SIZE 8192
@@ -698,10 +710,11 @@ static int input (void );
 
 /* 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 do { if (fwrite( ce_exprtext, ce_exprleng, 1, ce_exprout )) {} } while (0)
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
+/* %if-c++-only C++ definition */
+#define ECHO LexerOutput( yytext, yyleng )
+/* %endif */
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -709,34 +722,12 @@ static int input (void );
  */
 #ifndef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-		{ \
-		int c = '*'; \
-		unsigned 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); \
-			} \
-		}\
+/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\
 \
+/* %if-c++-only C++ definition \ */\
+	if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+/* %endif */
 
 #endif
 
@@ -755,23 +746,39 @@ static int input (void );
 
 /* Report a fatal error. */
 #ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+#define YY_FATAL_ERROR(msg) LexerError( msg )
+/* %endif */
 #endif
 
+/* %if-tables-serialization structures and prototypes */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* %tables-yydmap generated elements */
+/* %endif */
 /* end tables serialization structures and prototypes */
 
+/* %ok-for-header */
+
 /* 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)
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
+/* %if-c++-only C++ definition */
+#define YY_DECL int yyFlexLexer::yylex()
+/* %endif */
 #endif /* !YY_DECL */
 
-/* Code executed at the beginning of each rule, after ce_exprtext and ce_exprleng
+/* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
  */
 #ifndef YY_USER_ACTION
@@ -783,9 +790,12 @@ extern int ce_exprlex (void);
 #define YY_BREAK break;
 #endif
 
+/* %% [6.0] YY_RULE_SETUP definition goes here */
 #define YY_RULE_SETUP \
 	YY_USER_ACTION
 
+/* %not-for-header */
+
 /** The main scanner function which does all the work.
  */
 YY_DECL
@@ -794,10 +804,16 @@ YY_DECL
 	register char *yy_cp, *yy_bp;
 	register int yy_act;
     
-#line 132 "ce_expr.lex"
+/* %% [7.0] user's declarations go here */
+#line 114 "d4_function_scanner.ll"
+
+
+
+// Code run each time yylex is called
+loc->step();
 
 
-#line 801 "lex.ce_expr.cc"
+#line 817 "lex.d4_function.cc"
 
 	if ( !(yy_init) )
 		{
@@ -810,23 +826,32 @@ YY_DECL
 		if ( ! (yy_start) )
 			(yy_start) = 1;	/* first start state */
 
-		if ( ! ce_exprin )
-			ce_exprin = stdin;
+		if ( ! yyin )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+			yyin = & std::cin;
+/* %endif */
 
-		if ( ! ce_exprout )
-			ce_exprout = stdout;
+		if ( ! yyout )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+			yyout = & std::cout;
+/* %endif */
 
 		if ( ! YY_CURRENT_BUFFER ) {
-			ce_exprensure_buffer_stack ();
+			yyensure_buffer_stack ();
 			YY_CURRENT_BUFFER_LVALUE =
-				ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+				yy_create_buffer( yyin, YY_BUF_SIZE );
 		}
 
-		ce_expr_load_buffer_state( );
+		yy_load_buffer_state(  );
 		}
 
 	while ( 1 )		/* loops until end-of-file is reached */
 		{
+/* %% [8.0] yymore()-related code goes here */
 		(yy_more_len) = 0;
 		if ( (yy_more_flag) )
 			{
@@ -835,7 +860,7 @@ YY_DECL
 			}
 		yy_cp = (yy_c_buf_p);
 
-		/* Support of ce_exprtext. */
+		/* Support of yytext. */
 		*yy_cp = (yy_hold_char);
 
 		/* yy_bp points to the position in yy_ch_buf of the start of
@@ -843,6 +868,7 @@ YY_DECL
 		 */
 		yy_bp = yy_cp;
 
+/* %% [9.0] code to set up and find next match goes here */
 		yy_current_state = (yy_start);
 yy_match:
 		do
@@ -856,29 +882,55 @@ yy_match:
 			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 >= 66 )
+				if ( yy_current_state >= 64 )
 					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] != 95 );
+		while ( yy_current_state != 63 );
+		yy_cp = (yy_last_accepting_cpos);
+		yy_current_state = (yy_last_accepting_state);
 
 yy_find_action:
+/* %% [10.0] code to find the action number goes here */
 		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;
 
+/* %% [11.0] code for yylineno update goes here */
+
+		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+			{
+			yy_size_t yyl;
+			for ( yyl = (yy_more_len); yyl < yyleng; ++yyl )
+				if ( yytext[yyl] == '\n' )
+					   
+    yylineno++;
+;
+			}
+
 do_action:	/* This label is used only to access EOF actions. */
 
+/* %% [12.0] debug code goes here */
+		if ( yy_flex_debug )
+			{
+			if ( yy_act == 0 )
+				std::cerr << "--scanner backing up\n";
+			else if ( yy_act < 29 )
+				std::cerr << "--accepting rule at line " << yy_rule_linenum[yy_act] <<
+				         "(\"" << yytext << "\")\n";
+			else if ( yy_act == 29 )
+				std::cerr << "--accepting default rule (\"" << yytext << "\")\n";
+			else if ( yy_act == 30 )
+				std::cerr << "--(end of buffer or a NUL)\n";
+			else
+				std::cerr << "--EOF (start condition " << YY_START << ")\n";
+			}
+
 		switch ( yy_act )
 	{ /* beginning of action switch */
+/* %% [13.0] actions go here */
 			case 0: /* must back up */
 			/* undo the effects of YY_DO_BEFORE_ACTION */
 			*yy_cp = (yy_hold_char);
@@ -888,190 +940,178 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 134 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 121 "d4_function_scanner.ll"
+return token::COMMA;
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 135 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 122 "d4_function_scanner.ll"
+return token::SEMICOLON;
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 136 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 123 "d4_function_scanner.ll"
+return token::COLON;
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 137 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 125 "d4_function_scanner.ll"
+return token::LPAREN;
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 138 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 126 "d4_function_scanner.ll"
+return token::RPAREN;
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 139 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 128 "d4_function_scanner.ll"
+return token::GROUP_SEP;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 140 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 129 "d4_function_scanner.ll"
+return token::PATH_SEP;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 141 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 131 "d4_function_scanner.ll"
+return token::DOLLAR_BYTE;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 142 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 132 "d4_function_scanner.ll"
+return token::DOLLAR_UINT8;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 144 "ce_expr.lex"
-store_id(); return SCAN_WORD;
+#line 133 "d4_function_scanner.ll"
+return token::DOLLAR_INT8;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 146 "ce_expr.lex"
-store_op(SCAN_EQUAL); return SCAN_EQUAL;
+#line 134 "d4_function_scanner.ll"
+return token::DOLLAR_UINT16;
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 147 "ce_expr.lex"
-store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
+#line 135 "d4_function_scanner.ll"
+return token::DOLLAR_INT16;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 148 "ce_expr.lex"
-store_op(SCAN_GREATER); return SCAN_GREATER;
+#line 136 "d4_function_scanner.ll"
+return token::DOLLAR_UINT32;
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 149 "ce_expr.lex"
-store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
+#line 137 "d4_function_scanner.ll"
+return token::DOLLAR_INT32;
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 150 "ce_expr.lex"
-store_op(SCAN_LESS); return SCAN_LESS;
+#line 138 "d4_function_scanner.ll"
+return token::DOLLAR_UINT64;
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 151 "ce_expr.lex"
-store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
+#line 139 "d4_function_scanner.ll"
+return token::DOLLAR_INT64;
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 152 "ce_expr.lex"
-store_op(SCAN_REGEXP); return SCAN_REGEXP;
+#line 140 "d4_function_scanner.ll"
+return token::DOLLAR_FLOAT32;
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 154 "ce_expr.lex"
-store_op(SCAN_STAR); return SCAN_STAR;
+#line 141 "d4_function_scanner.ll"
+return token::DOLLAR_FLOAT64;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 156 "ce_expr.lex"
-return SCAN_HASH_BYTE;
+#line 143 "d4_function_scanner.ll"
+/* ignore these */
 	YY_BREAK
 case 20:
+/* rule 20 can match eol */
 YY_RULE_SETUP
-#line 157 "ce_expr.lex"
-return SCAN_HASH_INT16;
+#line 145 "d4_function_scanner.ll"
+/* ignore these */
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 158 "ce_expr.lex"
-return SCAN_HASH_UINT16;
+#line 147 "d4_function_scanner.ll"
+{ yylval->build<std::string>(yytext); return token::WORD; }
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 149 "d4_function_scanner.ll"
+return token::END;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 159 "ce_expr.lex"
-return SCAN_HASH_INT32;
+#line 151 "d4_function_scanner.ll"
+{ BEGIN(quote); yymore(); }
 	YY_BREAK
 case 23:
+/* rule 23 can match eol */
 YY_RULE_SETUP
-#line 160 "ce_expr.lex"
-return SCAN_HASH_UINT32;
+#line 153 "d4_function_scanner.ll"
+yymore(); /* Anything that's not a double quote or a backslash */
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 161 "ce_expr.lex"
-return SCAN_HASH_FLOAT32;
+#line 155 "d4_function_scanner.ll"
+yymore(); /* This matches the escaped double quote (\") */
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 162 "ce_expr.lex"
-return SCAN_HASH_FLOAT64;
+#line 157 "d4_function_scanner.ll"
+yymore(); /* This matches an escaped escape (\\) */
 	YY_BREAK
 case 26:
-/* rule 26 can match eol */
 YY_RULE_SETUP
-#line 164 "ce_expr.lex"
-
-	YY_BREAK
-case YY_STATE_EOF(INITIAL):
-#line 165 "ce_expr.lex"
-yy_init = 1; yyterminate();
+#line 159 "d4_function_scanner.ll"
+{
+                    BEGIN(INITIAL);
+                    if (yytext) {
+                        YY_FATAL_ERROR("Inside a string, backslash (\\) can escape a double quote or must itself be escaped (\\\\).");
+                    }
+                }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 167 "ce_expr.lex"
-BEGIN(quote); yymore();
-	YY_BREAK
-case 28:
-/* rule 28 can match eol */
-YY_RULE_SETUP
-#line 169 "ce_expr.lex"
-yymore(); /*"*/
-	YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 171 "ce_expr.lex"
-yymore();
-	YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 173 "ce_expr.lex"
+#line 166 "d4_function_scanner.ll"
 { 
-    		  BEGIN(INITIAL); 
-              store_str();
-              return SCAN_STR;
+                /* An unescaped double quote in the 'quote' state indicates the end of the string */
+                BEGIN(INITIAL); 
+                yylval->build<std::string>(yytext); 
+                return token::STRING;
             }
 	YY_BREAK
 case YY_STATE_EOF(quote):
-#line 179 "ce_expr.lex"
+#line 173 "d4_function_scanner.ll"
 {
                   BEGIN(INITIAL);   /* resetting the state is needed for reentrant parsers */
-                  char msg[256];
-                  sprintf(msg, "Unterminated quote\n");
-                  YY_FATAL_ERROR(msg);
+                  YY_FATAL_ERROR("Unterminated quote");
                 }
 	YY_BREAK
-case 31:
-/* rule 31 can match eol */
+case 28:
 YY_RULE_SETUP
-#line 186 "ce_expr.lex"
+#line 178 "d4_function_scanner.ll"
 {
-                  if (ce_exprtext) {	/* suppress msgs about `' chars */
-                    fprintf(stderr, "Character `%c' is not", *ce_exprtext);
-                    fprintf(stderr, " allowed and has been ignored\n");
-                  }
-		        }
+        BEGIN(INITIAL);
+        if (yytext) {
+            YY_FATAL_ERROR("Characters found in the input were not recognized.");
+        }
+    }
 	YY_BREAK
-case 32:
+case 29:
 YY_RULE_SETUP
-#line 192 "ce_expr.lex"
-ECHO;
+#line 184 "d4_function_scanner.ll"
+YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 1075 "lex.ce_expr.cc"
+#line 1115 "lex.d4_function.cc"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1086,15 +1126,15 @@ ECHO;
 			{
 			/* 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
+			 * just pointed yyin at a new source and called
+			 * yylex().  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_input_file = yyin;
 			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
 			}
 
@@ -1136,7 +1176,9 @@ ECHO;
 
 			else
 				{
-				yy_cp = (yy_c_buf_p);
+/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
+				yy_cp = (yy_last_accepting_cpos);
+				yy_current_state = (yy_last_accepting_state);
 				goto yy_find_action;
 				}
 			}
@@ -1147,11 +1189,11 @@ ECHO;
 				{
 				(yy_did_buffer_switch_on_eof) = 0;
 
-				if ( ce_exprwrap( ) )
+				if ( yywrap(  ) )
 					{
 					/* Note: because we've taken care in
 					 * yy_get_next_buffer() to have set up
-					 * ce_exprtext, we can now set up
+					 * yytext, 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
@@ -1200,7 +1242,103 @@ ECHO;
 			"fatal flex scanner internal error--no action found" );
 	} /* end of action switch */
 		} /* end of scanning one token */
-} /* end of ce_exprlex */
+} /* end of yylex */
+/* %ok-for-header */
+
+/* %if-c++-only */
+/* %not-for-header */
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout )
+{
+	yyin = arg_yyin;
+	yyout = arg_yyout;
+	yy_c_buf_p = 0;
+	yy_init = 0;
+	yy_start = 0;
+	yy_flex_debug = 0;
+	yylineno = 1;	// this will only get updated if %option yylineno
+
+	yy_did_buffer_switch_on_eof = 0;
+
+	yy_looking_for_trail_begin = 0;
+	yy_more_flag = 0;
+	yy_more_len = 0;
+	yy_more_offset = yy_prev_more_offset = 0;
+
+	yy_start_stack_ptr = yy_start_stack_depth = 0;
+	yy_start_stack = NULL;
+
+	yy_buffer_stack = 0;
+	yy_buffer_stack_top = 0;
+	yy_buffer_stack_max = 0;
+
+	yy_state_buf = 0;
+
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::~yyFlexLexer()
+{
+	delete [] yy_state_buf;
+	d4_functionfree(yy_start_stack  );
+	yy_delete_buffer( YY_CURRENT_BUFFER );
+	d4_functionfree(yy_buffer_stack  );
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out )
+{
+	if ( new_in )
+		{
+		yy_delete_buffer( YY_CURRENT_BUFFER );
+		yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE  ) );
+		}
+
+	if ( new_out )
+		yyout = new_out;
+}
+
+#ifdef YY_INTERACTIVE
+size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ )
+#else
+size_t yyFlexLexer::LexerInput( char* buf, size_t max_size )
+#endif
+{
+	if ( yyin->eof() || yyin->fail() )
+		return 0;
+
+#ifdef YY_INTERACTIVE
+	yyin->get( buf[0] );
+
+	if ( yyin->eof() )
+		return 0;
+
+	if ( yyin->bad() )
+		return -1;
+
+	return 1;
+
+#else
+	(void) yyin->read( buf, max_size );
+
+	if ( yyin->bad() )
+		return -1;
+	else
+		return yyin->gcount();
+#endif
+}
+
+void yyFlexLexer::LexerOutput( const char* buf, size_t size )
+{
+	(void) yyout->write( buf, size );
+}
+/* %ok-for-header */
+
+/* %endif */
 
 /* yy_get_next_buffer - try to read in a new buffer
  *
@@ -1209,7 +1347,11 @@ ECHO;
  *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  *	EOB_ACT_END_OF_FILE - end of file
  */
-static int yy_get_next_buffer (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+int yyFlexLexer::yy_get_next_buffer()
+/* %endif */
 {
     	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
 	register char *source = (yytext_ptr);
@@ -1255,7 +1397,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1269,7 +1411,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1278,7 +1420,7 @@ static int yy_get_next_buffer (void)
 
 				b->yy_ch_buf = (char *)
 					/* Include room in for 2 EOB chars. */
-					ce_exprrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+					d4_functionrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
 				}
 			else
 				/* Can't grow it, we don't own it. */
@@ -1300,7 +1442,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1310,7 +1452,7 @@ static int yy_get_next_buffer (void)
 		if ( number_to_move == YY_MORE_ADJ )
 			{
 			ret_val = EOB_ACT_END_OF_FILE;
-			ce_exprrestart(ce_exprin  );
+			yyrestart( yyin  );
 			}
 
 		else
@@ -1327,7 +1469,7 @@ static int yy_get_next_buffer (void)
 	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ce_exprrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) d4_functionrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
 	}
@@ -1343,15 +1485,23 @@ static int yy_get_next_buffer (void)
 
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
-    static yy_state_type yy_get_previous_state (void)
+/* %if-c-only */
+/* %not-for-header */
+
+/* %endif */
+/* %if-c++-only */
+    yy_state_type yyFlexLexer::yy_get_previous_state()
+/* %endif */
 {
 	register yy_state_type yy_current_state;
 	register char *yy_cp;
     
+/* %% [15.0] code to get the start state into yy_current_state goes here */
 	yy_current_state = (yy_start);
 
 	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
 		{
+/* %% [16.0] code to find the next state goes here */
 		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
 		if ( yy_accept[yy_current_state] )
 			{
@@ -1361,7 +1511,7 @@ static int yy_get_next_buffer (void)
 		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 >= 66 )
+			if ( yy_current_state >= 64 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1375,10 +1525,15 @@ static int yy_get_next_buffer (void)
  * synopsis
  *	next_state = yy_try_NUL_trans( current_state );
  */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state )
+/* %endif */
 {
 	register int yy_is_jam;
-    	register char *yy_cp = (yy_c_buf_p);
+    /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */
+	register char *yy_cp = (yy_c_buf_p);
 
 	register YY_CHAR yy_c = 1;
 	if ( yy_accept[yy_current_state] )
@@ -1389,22 +1544,69 @@ static int yy_get_next_buffer (void)
 	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 >= 66 )
+		if ( yy_current_state >= 64 )
 			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 == 65);
+	yy_is_jam = (yy_current_state == 63);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
 
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yyunput( int c, register char* yy_bp)
+/* %endif */
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up yytext */
+	*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 yy_size_t 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;
+
+/* %% [18.0] update yylineno here */
+
+    if ( c == '\n' ){
+        --yylineno;
+    }
 
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+/* %if-c-only */
+/* %endif */
+
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    int yyFlexLexer::yyinput()
+/* %endif */
 {
 	int c;
     
@@ -1422,7 +1624,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1439,14 +1641,14 @@ static int yy_get_next_buffer (void)
 					 */
 
 					/* Reset buffer status. */
-					ce_exprrestart(ce_exprin );
+					yyrestart( yyin );
 
 					/*FALLTHROUGH*/
 
 				case EOB_ACT_END_OF_FILE:
 					{
-					if ( ce_exprwrap( ) )
-						return EOF;
+					if ( yywrap(  ) )
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1465,44 +1667,59 @@ static int yy_get_next_buffer (void)
 		}
 
 	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve ce_exprtext */
+	*(yy_c_buf_p) = '\0';	/* preserve yytext */
 	(yy_hold_char) = *++(yy_c_buf_p);
 
+/* %% [19.0] update BOL and yylineno */
+	if ( c == '\n' )
+		   
+    yylineno++;
+;
+
 	return c;
 }
-#endif	/* ifndef YY_NO_INPUT */
+/* %if-c-only */
+/* %endif */
 
 /** 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-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yyrestart( std::istream* input_file )
+/* %endif */
 {
     
 	if ( ! YY_CURRENT_BUFFER ){
-        ce_exprensure_buffer_stack ();
+        yyensure_buffer_stack ();
 		YY_CURRENT_BUFFER_LVALUE =
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+            yy_create_buffer( yyin, YY_BUF_SIZE );
 	}
 
-	ce_expr_init_buffer(YY_CURRENT_BUFFER,input_file );
-	ce_expr_load_buffer_state( );
+	yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+	yy_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 )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+/* %endif */
 {
     
 	/* TODO. We should be able to replace this entire function body
 	 * with
-	 *		ce_exprpop_buffer_state();
-	 *		ce_exprpush_buffer_state(new_buffer);
+	 *		yypop_buffer_state();
+	 *		yypush_buffer_state(new_buffer);
      */
-	ce_exprensure_buffer_stack ();
+	yyensure_buffer_stack ();
 	if ( YY_CURRENT_BUFFER == new_buffer )
 		return;
 
@@ -1515,21 +1732,25 @@ static int yy_get_next_buffer (void)
 		}
 
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	ce_expr_load_buffer_state( );
+	yy_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
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() 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)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_load_buffer_state()
+/* %endif */
 {
     	(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;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
 	(yy_hold_char) = *(yy_c_buf_p);
 }
 
@@ -1539,35 +1760,43 @@ static void ce_expr_load_buffer_state  (void)
  * 
  * @return the allocated buffer state.
  */
-    YY_BUFFER_STATE ce_expr_create_buffer  (FILE * file, int  size )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size )
+/* %endif */
 {
 	YY_BUFFER_STATE b;
     
-	b = (YY_BUFFER_STATE) ce_expralloc(sizeof( struct yy_buffer_state )  );
+	b = (YY_BUFFER_STATE) d4_functionalloc(sizeof( struct yy_buffer_state )  );
 	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_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  );
+	b->yy_ch_buf = (char *) d4_functionalloc(b->yy_buf_size + 2  );
 	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
 	b->yy_is_our_buffer = 1;
 
-	ce_expr_init_buffer(b,file );
+	yy_init_buffer( b, file );
 
 	return b;
 }
 
 /** Destroy the buffer.
- * @param b a buffer created with ce_expr_create_buffer()
+ * @param b a buffer created with yy_create_buffer()
  * 
  */
-    void ce_expr_delete_buffer (YY_BUFFER_STATE  b )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b )
+/* %endif */
 {
     
 	if ( ! b )
@@ -1577,31 +1806,40 @@ static void ce_expr_load_buffer_state  (void)
 		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
 
 	if ( b->yy_is_our_buffer )
-		ce_exprfree((void *) b->yy_ch_buf  );
+		d4_functionfree((void *) b->yy_ch_buf  );
 
-	ce_exprfree((void *) b  );
+	d4_functionfree((void *) b  );
 }
 
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
+/* %if-c-only */
+/* %endif */
+
+/* %if-c++-only */
+
+extern "C" int isatty (int );
+
+/* %endif */
+
 /* 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.
+ * such as during a yyrestart() or at EOF.
  */
-    static void ce_expr_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file )
+/* %endif */
 
 {
 	int oerrno = errno;
     
-	ce_expr_flush_buffer(b );
+	yy_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.
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
      * In that case, we don't want to reset the lineno or column.
      */
     if (b != YY_CURRENT_BUFFER){
@@ -1609,8 +1847,11 @@ extern int isatty (int );
         b->yy_bs_column = 0;
     }
 
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+	b->yy_is_interactive = 0;
+/* %endif */
 	errno = oerrno;
 }
 
@@ -1618,7 +1859,11 @@ extern int isatty (int );
  * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
  * 
  */
-    void ce_expr_flush_buffer (YY_BUFFER_STATE  b )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b )
+/* %endif */
 {
     	if ( ! b )
 		return;
@@ -1638,23 +1883,28 @@ extern int isatty (int );
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
 	if ( b == YY_CURRENT_BUFFER )
-		ce_expr_load_buffer_state( );
+		yy_load_buffer_state(  );
 }
 
+/* %if-c-or-c++ */
 /** 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-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer)
+/* %endif */
 {
     	if (new_buffer == NULL)
 		return;
 
-	ce_exprensure_buffer_stack();
+	yyensure_buffer_stack();
 
-	/* This block is copied from ce_expr_switch_to_buffer. */
+	/* This block is copied from yy_switch_to_buffer. */
 	if ( YY_CURRENT_BUFFER )
 		{
 		/* Flush out information for old buffer. */
@@ -1668,37 +1918,49 @@ void ce_exprpush_buffer_state (YY_BUFFER_STATE new_buffer )
 		(yy_buffer_stack_top)++;
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
 
-	/* copied from ce_expr_switch_to_buffer. */
-	ce_expr_load_buffer_state( );
+	/* copied from yy_switch_to_buffer. */
+	yy_load_buffer_state(  );
 	(yy_did_buffer_switch_on_eof) = 1;
 }
+/* %endif */
 
+/* %if-c-or-c++ */
 /** Removes and deletes the top of the stack, if present.
  *  The next element becomes the new top.
  *  
  */
-void ce_exprpop_buffer_state (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yypop_buffer_state (void)
+/* %endif */
 {
     	if (!YY_CURRENT_BUFFER)
 		return;
 
-	ce_expr_delete_buffer(YY_CURRENT_BUFFER );
+	yy_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_load_buffer_state(  );
 		(yy_did_buffer_switch_on_eof) = 1;
 	}
 }
+/* %endif */
 
+/* %if-c-or-c++ */
 /* Allocates the stack if it does not exist.
  *  Guarantees space for at least one push.
  */
-static void ce_exprensure_buffer_stack (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yyensure_buffer_stack(void)
+/* %endif */
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1707,11 +1969,11 @@ static void ce_exprensure_buffer_stack (void)
 		 * immediate realloc on the next call.
          */
 		num_to_alloc = 1;
-		(yy_buffer_stack) = (struct yy_buffer_state**)ce_expralloc
+		(yy_buffer_stack) = (struct yy_buffer_state**)d4_functionalloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ce_exprensure_buffer_stack()" );
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 								  
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 				
@@ -1726,114 +1988,91 @@ static void ce_exprensure_buffer_stack (void)
 		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) = (struct yy_buffer_state**)d4_functionrealloc
 								((yy_buffer_stack),
 								num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ce_exprensure_buffer_stack()" );
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 
 		/* 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;
 	}
 }
+/* %endif */
 
-/** 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;
+/* %if-c-only */
+/* %endif */
 
-	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()" );
+/* %if-c-only */
+/* %endif */
 
-	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;
+/* %if-c-only */
+/* %endif */
 
-	ce_expr_switch_to_buffer(b  );
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_push_state( int new_state )
+/* %endif */
+{
+    	if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) )
+		{
+		yy_size_t new_size;
 
-	return b;
-}
+		(yy_start_stack_depth) += YY_START_STACK_INCR;
+		new_size = (yy_start_stack_depth) * sizeof( int );
 
-/** 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 yystr 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) );
-}
+		if ( ! (yy_start_stack) )
+			(yy_start_stack) = (int *) d4_functionalloc(new_size  );
 
-/** 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()" );
+		else
+			(yy_start_stack) = (int *) d4_functionrealloc((void *) (yy_start_stack),new_size  );
 
-	for ( i = 0; i < _yybytes_len; ++i )
-		buf[i] = yybytes[i];
+		if ( ! (yy_start_stack) )
+			YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+		}
 
-	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+	(yy_start_stack)[(yy_start_stack_ptr)++] = YY_START;
 
-	b = ce_expr_scan_buffer(buf,n );
-	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in ce_expr_scan_bytes()" );
+	BEGIN(new_state);
+}
 
-	/* It's okay to grow etc. this buffer, and we should throw it
-	 * away when we're done.
-	 */
-	b->yy_is_our_buffer = 1;
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_pop_state()
+/* %endif */
+{
+    	if ( --(yy_start_stack_ptr) < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
 
-	return b;
+	BEGIN((yy_start_stack)[(yy_start_stack_ptr)]);
+}
+
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    int yyFlexLexer::yy_top_state()
+/* %endif */
+{
+    	return (yy_start_stack)[(yy_start_stack_ptr) - 1];
 }
 
 #ifndef YY_EXIT_FAILURE
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yy_fatal_error (yyconst char* msg )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::LexerError( yyconst char msg[] )
 {
-    	(void) fprintf( stderr, "%s\n", msg );
+    	std::cerr << msg << std::endl;
 	exit( YY_EXIT_FAILURE );
 }
+/* %endif */
 
 /* Redefine yyless() so it works in section 3 code. */
 
@@ -1841,146 +2080,38 @@ static void yy_fatal_error (yyconst char* msg )
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ce_exprtext. */ \
+		/* Undo effects of setting up yytext. */ \
         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; \
+		yytext[yyleng] = (yy_hold_char); \
+		(yy_c_buf_p) = yytext + yyless_macro_arg; \
 		(yy_hold_char) = *(yy_c_buf_p); \
 		*(yy_c_buf_p) = '\0'; \
-		ce_exprleng = yyless_macro_arg; \
+		yyleng = 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;
-}
+/* %if-c-only */
+/* %if-reentrant */
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif */
 
-/** 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;
-}
+/* %if-reentrant */
+/* %if-bison-bridge */
+/* %endif */
+/* %endif if-c-only */
 
-/** 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 ;
-}
+/* %if-c-only */
+/* %endif */
 
-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;
-}
+/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
+/* %if-reentrant */
+/* %endif */
+/* %endif */
 
 /*
  * Internal utility routines.
@@ -2006,12 +2137,12 @@ static int yy_flex_strlen (yyconst char * s )
 }
 #endif
 
-void *ce_expralloc (yy_size_t  size )
+void *d4_functionalloc (yy_size_t  size )
 {
 	return (void *) malloc( size );
 }
 
-void *ce_exprrealloc  (void * ptr, yy_size_t  size )
+void *d4_functionrealloc  (void * ptr, yy_size_t  size )
 {
 	/* The cast to (char *) in the following accommodates both
 	 * implementations that use char* generic pointers, and those
@@ -2023,69 +2154,19 @@ void *ce_exprrealloc  (void * ptr, yy_size_t  size )
 	return (void *) realloc( (char *) ptr, size );
 }
 
-void ce_exprfree (void * ptr )
+void d4_functionfree (void * ptr )
 {
-	free( (char *) ptr );	/* see ce_exprrealloc() for (char *) cast */
+	free( (char *) ptr );	/* see d4_functionrealloc() for (char *) cast */
 }
 
+/* %if-tables-serialization definitions */
+/* %define-yytables   The name for this specific scanner's tables. */
 #define YYTABLES_NAME "yytables"
+/* %endif */
 
-#line 192 "ce_expr.lex"
+/* %ok-for-header */
 
+#line 184 "d4_function_scanner.ll"
 
 
-// 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, ce_exprtext, 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(ce_exprtext); // move all calls of www2id into the parser. jhrg 7/5/13 www2id(string(ce_exprtext)));
-
-    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/d4_ce/gen_grammar_sources/location.hh.tmp b/d4_ce/gen_grammar_sources/location.hh.tmp
new file mode 100644
index 0000000..d78dc0a
--- /dev/null
+++ b/d4_ce/gen_grammar_sources/location.hh.tmp
@@ -0,0 +1,187 @@
+// A Bison parser, made by GNU Bison 3.0.
+
+// Locations for Bison parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file location.hh
+ ** Define the libdap::location class.
+ */
+
+#ifndef YY_YY_LOCATION_HH_INCLUDED
+# define YY_YY_LOCATION_HH_INCLUDED
+
+# include "position.hh"
+
+#line 34 "d4_function_parser.yy" // location.cc:332
+namespace libdap {
+#line 46 "location.hh" // location.cc:332
+  /// Abstract a location.
+  class location
+  {
+  public:
+
+    /// Construct a location from \a b to \a e.
+    location (const position& b, const position& e)
+      : begin (b)
+      , end (e)
+    {
+    }
+
+    /// Construct a 0-width location in \a p.
+    explicit location (const position& p = position ())
+      : begin (p)
+      , end (p)
+    {
+    }
+
+    /// Construct a 0-width location in \a f, \a l, \a c.
+    explicit location (std::string* f,
+                       unsigned int l = 1u,
+                       unsigned int c = 1u)
+      : begin (f, l, c)
+      , end (f, l, c)
+    {
+    }
+
+
+    /// Initialization.
+    void initialize (std::string* f = YY_NULL,
+                     unsigned int l = 1u,
+                     unsigned int c = 1u)
+    {
+      begin.initialize (f, l, c);
+      end = begin;
+    }
+
+    /** \name Line and Column related manipulators
+     ** \{ */
+  public:
+    /// Reset initial location to final location.
+    void step ()
+    {
+      begin = end;
+    }
+
+    /// Extend the current location to the COUNT next columns.
+    void columns (int count = 1)
+    {
+      end += count;
+    }
+
+    /// Extend the current location to the COUNT next lines.
+    void lines (int count = 1)
+    {
+      end.lines (count);
+    }
+    /** \} */
+
+
+  public:
+    /// Beginning of the located region.
+    position begin;
+    /// End of the located region.
+    position end;
+  };
+
+  /// Join two location objects to create a location.
+  inline location operator+ (location res, const location& end)
+  {
+    res.end = end.end;
+    return res;
+  }
+
+  /// Change end position in place.
+  inline location& operator+= (location& res, int width)
+  {
+    res.columns (width);
+    return res;
+  }
+
+  /// Change end position.
+  inline location operator+ (location res, int width)
+  {
+    return res += width;
+  }
+
+  /// Change end position in place.
+  inline location& operator-= (location& res, int width)
+  {
+    return res += -width;
+  }
+
+  /// Change end position.
+  inline location operator- (const location& begin, int width)
+  {
+    return begin + -width;
+  }
+
+  /// Compare two location objects.
+  inline bool
+  operator== (const location& loc1, const location& loc2)
+  {
+    return loc1.begin == loc2.begin && loc1.end == loc2.end;
+  }
+
+  /// Compare two location objects.
+  inline bool
+  operator!= (const location& loc1, const location& loc2)
+  {
+    return !(loc1 == loc2);
+  }
+
+  /** \brief Intercept output stream redirection.
+   ** \param ostr the destination output stream
+   ** \param loc a reference to the location to redirect
+   **
+   ** Avoid duplicate information.
+   */
+  template <typename YYChar>
+  inline std::basic_ostream<YYChar>&
+  operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
+  {
+    unsigned int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
+    ostr << loc.begin// << "(" << loc.end << ") "
+;
+    if (loc.end.filename
+        && (!loc.begin.filename
+            || *loc.begin.filename != *loc.end.filename))
+      ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
+    else if (loc.begin.line < loc.end.line)
+      ostr << '-' << loc.end.line << '.' << end_col;
+    else if (loc.begin.column < end_col)
+      ostr << '-' << end_col;
+    return ostr;
+  }
+
+#line 34 "d4_function_parser.yy" // location.cc:332
+} // libdap
+#line 187 "location.hh" // location.cc:332
+#endif // !YY_YY_LOCATION_HH_INCLUDED
diff --git a/d4_ce/gen_grammar_sources/position.hh.tmp b/d4_ce/gen_grammar_sources/position.hh.tmp
new file mode 100644
index 0000000..c0275c1
--- /dev/null
+++ b/d4_ce/gen_grammar_sources/position.hh.tmp
@@ -0,0 +1,180 @@
+// A Bison parser, made by GNU Bison 3.0.
+
+// Positions for Bison parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file position.hh
+ ** Define the libdap::position class.
+ */
+
+#ifndef YY_YY_POSITION_HH_INCLUDED
+# define YY_YY_POSITION_HH_INCLUDED
+
+# include <algorithm> // std::max
+# include <iostream>
+# include <string>
+
+# ifndef YY_NULL
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULL nullptr
+#  else
+#   define YY_NULL 0
+#  endif
+# endif
+
+#line 34 "d4_function_parser.yy" // location.cc:332
+namespace libdap {
+#line 56 "position.hh" // location.cc:332
+  /// Abstract a position.
+  class position
+  {
+  public:
+    /// Construct a position.
+    explicit position (std::string* f = YY_NULL,
+                       unsigned int l = 1u,
+                       unsigned int c = 1u)
+      : filename (f)
+      , line (l)
+      , column (c)
+    {
+    }
+
+
+    /// Initialization.
+    void initialize (std::string* fn = YY_NULL,
+                     unsigned int l = 1u,
+                     unsigned int c = 1u)
+    {
+      filename = fn;
+      line = l;
+      column = c;
+    }
+
+    /** \name Line and Column related manipulators
+     ** \{ */
+    /// (line related) Advance to the COUNT next lines.
+    void lines (int count = 1)
+    {
+      if (count)
+        {
+          column = 1u;
+          line = add_ (line, count, 1);
+        }
+    }
+
+    /// (column related) Advance to the COUNT next columns.
+    void columns (int count = 1)
+    {
+      column = add_ (column, count, 1);
+    }
+    /** \} */
+
+    /// File name to which this position refers.
+    std::string* filename;
+    /// Current line number.
+    unsigned int line;
+    /// Current column number.
+    unsigned int column;
+
+  private:
+    /// Compute max(min, lhs+rhs) (provided min <= lhs).
+    static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min)
+    {
+      return (0 < rhs || -static_cast<unsigned int>(rhs) < lhs
+              ? rhs + lhs
+              : min);
+    }
+  };
+
+  /// Add and assign a position.
+  inline position&
+  operator+= (position& res, int width)
+  {
+    res.columns (width);
+    return res;
+  }
+
+  /// Add two position objects.
+  inline position
+  operator+ (position res, int width)
+  {
+    return res += width;
+  }
+
+  /// Add and assign a position.
+  inline position&
+  operator-= (position& res, int width)
+  {
+    return res += -width;
+  }
+
+  /// Add two position objects.
+  inline position
+  operator- (position res, int width)
+  {
+    return res -= width;
+  }
+
+  /// Compare two position objects.
+  inline bool
+  operator== (const position& pos1, const position& pos2)
+  {
+    return (pos1.line == pos2.line
+            && pos1.column == pos2.column
+            && (pos1.filename == pos2.filename
+                || (pos1.filename && pos2.filename
+                    && *pos1.filename == *pos2.filename)));
+  }
+
+  /// Compare two position objects.
+  inline bool
+  operator!= (const position& pos1, const position& pos2)
+  {
+    return !(pos1 == pos2);
+  }
+
+  /** \brief Intercept output stream redirection.
+   ** \param ostr the destination output stream
+   ** \param pos a reference to the position to redirect
+   */
+  template <typename YYChar>
+  inline std::basic_ostream<YYChar>&
+  operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
+  {
+    if (pos.filename)
+      ostr << *pos.filename << ':';
+    return ostr << pos.line << '.' << pos.column;
+  }
+
+#line 34 "d4_function_parser.yy" // location.cc:332
+} // libdap
+#line 180 "position.hh" // location.cc:332
+#endif // !YY_YY_POSITION_HH_INCLUDED
diff --git a/d4_ce/gen_grammar_sources/stack.hh.tmp b/d4_ce/gen_grammar_sources/stack.hh.tmp
new file mode 100644
index 0000000..280d8af
--- /dev/null
+++ b/d4_ce/gen_grammar_sources/stack.hh.tmp
@@ -0,0 +1,158 @@
+// A Bison parser, made by GNU Bison 3.0.
+
+// Stack handling for Bison parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file stack.hh
+ ** Define the libdap::stack class.
+ */
+
+#ifndef YY_YY_STACK_HH_INCLUDED
+# define YY_YY_STACK_HH_INCLUDED
+
+# include <vector>
+
+#line 34 "d4_function_parser.yy" // stack.hh:152
+namespace libdap {
+#line 46 "stack.hh" // stack.hh:152
+  template <class T, class S = std::vector<T> >
+  class stack
+  {
+  public:
+    // Hide our reversed order.
+    typedef typename S::reverse_iterator iterator;
+    typedef typename S::const_reverse_iterator const_iterator;
+
+    stack ()
+      : seq_ ()
+    {
+    }
+
+    stack (unsigned int n)
+      : seq_ (n)
+    {
+    }
+
+    inline
+    T&
+    operator[] (unsigned int i)
+    {
+      return seq_[seq_.size () - 1 - i];
+    }
+
+    inline
+    const T&
+    operator[] (unsigned int i) const
+    {
+      return seq_[seq_.size () - 1 - i];
+    }
+
+    /// Steal the contents of \a t.
+    ///
+    /// Close to move-semantics.
+    inline
+    void
+    push (T& t)
+    {
+      seq_.push_back (T());
+      operator[](0).move (t);
+    }
+
+    inline
+    void
+    pop (unsigned int n = 1)
+    {
+      for (; n; --n)
+        seq_.pop_back ();
+    }
+
+    void
+    clear ()
+    {
+      seq_.clear ();
+    }
+
+    inline
+    typename S::size_type
+    size () const
+    {
+      return seq_.size ();
+    }
+
+    inline
+    const_iterator
+    begin () const
+    {
+      return seq_.rbegin ();
+    }
+
+    inline
+    const_iterator
+    end () const
+    {
+      return seq_.rend ();
+    }
+
+  private:
+    stack (const stack&);
+    stack& operator= (const stack&);
+    /// The wrapped container.
+    S seq_;
+  };
+
+  /// Present a slice of the top of a stack.
+  template <class T, class S = stack<T> >
+  class slice
+  {
+  public:
+    slice (const S& stack, unsigned int range)
+      : stack_ (stack)
+      , range_ (range)
+    {
+    }
+
+    inline
+    const T&
+    operator [] (unsigned int i) const
+    {
+      return stack_[range_ - i];
+    }
+
+  private:
+    const S& stack_;
+    unsigned int range_;
+  };
+
+#line 34 "d4_function_parser.yy" // stack.hh:152
+} // libdap
+#line 157 "stack.hh" // stack.hh:152
+
+#endif // !YY_YY_STACK_HH_INCLUDED
diff --git a/lex.ce_expr.cc b/d4_ce/lex.d4_ce.cc
similarity index 55%
copy from lex.ce_expr.cc
copy to d4_ce/lex.d4_ce.cc
index 8d2a9d6..becb9bd 100644
--- a/lex.ce_expr.cc
+++ b/d4_ce/lex.d4_ce.cc
@@ -1,29 +1,17 @@
-#line 2 "lex.ce_expr.cc"
 
-#line 4 "lex.ce_expr.cc"
+#line 3 "lex.d4_ce.cc"
 
 #define  YY_INT_ALIGNED short int
 
 /* A lexical scanner generated by flex */
 
-#define yy_create_buffer ce_expr_create_buffer
-#define yy_delete_buffer ce_expr_delete_buffer
-#define yy_flex_debug ce_expr_flex_debug
-#define yy_init_buffer ce_expr_init_buffer
-#define yy_flush_buffer ce_expr_flush_buffer
-#define yy_load_buffer_state ce_expr_load_buffer_state
-#define yy_switch_to_buffer ce_expr_switch_to_buffer
-#define yyin ce_exprin
-#define yyleng ce_exprleng
-#define yylex ce_exprlex
-#define yylineno ce_exprlineno
-#define yyout ce_exprout
-#define yyrestart ce_exprrestart
-#define yytext ce_exprtext
-#define yywrap ce_exprwrap
-#define yyalloc ce_expralloc
-#define yyrealloc ce_exprrealloc
-#define yyfree ce_exprfree
+/* %not-for-header */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+/* %endif */
+/* %endif */
+/* %ok-for-header */
 
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
@@ -33,16 +21,33 @@
 #define FLEX_BETA
 #endif
 
+/* %if-c++-only */
+    /* The c++ scanner is a mess. The FlexLexer.h header file relies on the
+     * following macro. This is required in order to pass the c++-multiple-scanners
+     * test in the regression suite. We get reports that it breaks inheritance.
+     * We will address this in a future release of flex, or omit the C++ scanner
+     * altogether.
+     */
+    #define yyFlexLexer d4_ceFlexLexer
+/* %endif */
+
+/* %if-c-only */
+/* %endif */
+
+/* %if-c-only */
+/* %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>
+/* %if-c-only */
+/* %endif */
 
+/* %if-tables-serialization */
+/* %endif */
 /* end standard C headers. */
 
+/* %if-c-or-c++ */
 /* flex integer type definitions */
 
 #ifndef FLEXINT_H
@@ -66,6 +71,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -106,6 +112,17 @@ typedef unsigned int flex_uint32_t;
 
 #endif /* ! FLEXINT_H */
 
+/* %endif */
+
+/* %if-c++-only */
+/* begin standard C++ headers. */
+#include <iostream> 
+#include <errno.h>
+#include <cstdlib>
+#include <cstring>
+/* end standard C++ headers. */
+/* %endif */
+
 #ifdef __cplusplus
 
 /* The "const" storage-class-modifier is valid. */
@@ -127,8 +144,13 @@ typedef unsigned int flex_uint32_t;
 #define yyconst
 #endif
 
+/* %not-for-header */
+
 /* Returned upon end-of-file. */
 #define YY_NULL 0
+/* %ok-for-header */
+
+/* %not-for-header */
 
 /* Promotes a possibly negative, possibly signed char to an unsigned
  * integer for use as an array index.  If the signed char is negative,
@@ -136,6 +158,14 @@ typedef unsigned int flex_uint32_t;
  * double cast.
  */
 #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+/* %ok-for-header */
+
+/* %if-reentrant */
+/* %endif */
+
+/* %if-not-reentrant */
+
+/* %endif */
 
 /* 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
@@ -154,7 +184,7 @@ typedef unsigned int flex_uint32_t;
 #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_NEW_FILE yyrestart( yyin  )
 
 #define YY_END_OF_BUFFER_CHAR 0
 
@@ -172,42 +202,65 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int ce_exprleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
 
-extern FILE *ce_exprin, *ce_exprout;
+/* %if-not-reentrant */
+extern yy_size_t yyleng;
+/* %endif */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+/* %endif */
+/* %endif */
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
 
-    #define YY_LESS_LINENO(n)
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+     *       access to the local variable yy_act. Since yyless() is a macro, it would break
+     *       existing scanners that call yyless() from OUTSIDE yylex. 
+     *       One obvious solution it to make yy_act a global. I tried that, and saw
+     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                yy_size_t yyl;\
+                for ( yyl = n; yyl < yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
     
 /* Return all but the first "n" matched characters back to the input stream. */
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ce_exprtext. */ \
+		/* Undo effects of setting up yytext. */ \
         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 */ \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
 		} \
 	while ( 0 )
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
 	{
-	FILE *yy_input_file;
+/* %if-c-only */
+/* %endif */
+
+/* %if-c++-only */
+	std::istream* yy_input_file;
+/* %endif */
 
 	char *yy_ch_buf;		/* input buffer */
 	char *yy_buf_pos;		/* current position in input buffer */
@@ -220,7 +273,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t 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
@@ -260,18 +313,22 @@ struct yy_buffer_state
 	 * 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.
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin 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. */
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+/* %if-not-reentrant */
+/* %endif */
+/* %ok-for-header */
+
+/* %endif */
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
@@ -288,51 +345,27 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
  */
 #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 );
+/* %if-c-only Standard (non-C++) definition */
+/* %if-not-reentrant */
+/* %not-for-header */
 
-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  );
+/* %ok-for-header */
 
-#define YY_FLUSH_BUFFER ce_expr_flush_buffer(YY_CURRENT_BUFFER )
+/* %endif */
+/* %endif */
 
-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 *d4_cealloc (yy_size_t  );
+void *d4_cerealloc (void *,yy_size_t  );
+void d4_cefree (void *  );
 
-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_new_buffer yy_create_buffer
 
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
-        ce_exprensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
@@ -340,49 +373,53 @@ void ce_exprfree (void *  );
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
-        ce_exprensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
 
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
+/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
 /* Begin user sect3 */
-
-#define ce_exprwrap(n) 1
 #define YY_SKIP_YYWRAP
 
-typedef unsigned char YY_CHAR;
+#define FLEX_DEBUG
 
-FILE *ce_exprin = (FILE *) 0, *ce_exprout = (FILE *) 0;
+typedef unsigned char YY_CHAR;
 
-typedef int yy_state_type;
+#define yytext_ptr yytext
 
-extern int ce_exprlineno;
+#include <FlexLexer.h>
 
-int ce_exprlineno = 1;
+int yyFlexLexer::yywrap() { return 1; }
+int yyFlexLexer::yylex()
+	{
+	LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" );
+	return 0;
+	}
 
-extern char *ce_exprtext;
-#define yytext_ptr ce_exprtext
+#define YY_DECL int D4CEScanner::yylex()
 
-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[]  );
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
 
 /* Done after the current pattern has been matched and before the
- * corresponding action - sets up ce_exprtext.
+ * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\
 	(yytext_ptr) -= (yy_more_len); \
-	ce_exprleng = (size_t) (yy_cp - (yytext_ptr)); \
+	yyleng = (yy_size_t) (yy_cp - (yytext_ptr)); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
+/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
 	(yy_c_buf_p) = yy_cp;
 
+/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
 #define YY_NUM_RULES 32
 #define YY_END_OF_BUFFER 33
 /* This struct is not used in this scanner,
@@ -392,33 +429,31 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[66] =
+static yyconst flex_int16_t yy_accept[46] =
     {   0,
-        0,    0,   28,   28,   33,   31,   26,   31,   27,   31,
-       10,    5,    6,    7,   18,    4,    3,   15,   11,   13,
-        1,    2,    8,    9,   32,   28,   30,   32,   26,   12,
-        0,    0,    0,    0,   10,   16,   17,   14,   28,   29,
-        0,    0,    0,    0,    0,    0,    0,    0,   19,    0,
-        0,    0,    0,    0,   20,   22,    0,    0,    0,    0,
-       21,   23,   24,   25,    0
+        0,    0,   26,   26,   33,   31,   22,   23,   23,   24,
+       25,   24,    4,   10,    9,    3,    5,   16,   11,   14,
+       24,    1,    2,    7,    6,    8,   24,   26,   30,   29,
+       22,   23,   24,   13,   19,   17,   12,   15,   20,   21,
+       18,   26,   27,   28,    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,    4,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    4,    5,    6,    7,    8,    9,    1,   10,
-       11,   12,    8,   13,    8,    8,    8,    8,   14,   15,
-       16,   17,    8,   18,    8,    8,    8,   19,    1,   20,
-       21,   22,    1,    1,    8,   23,    8,    8,    8,   24,
-        8,    8,   25,    8,    8,    8,    8,    8,    8,    8,
-        8,    8,    8,    8,   26,    8,    8,    8,    8,    8,
-       27,   28,   29,    1,    8,    1,   30,    8,    8,    8,
-
-       31,    8,    8,    8,    8,    8,    8,   32,    8,   33,
-       34,    8,    8,    8,    8,   35,    8,    8,    8,    8,
-       36,    8,   37,    1,   38,   39,    1,    1,    1,    1,
+        1,    2,    5,    6,    7,    1,    8,    1,    1,    1,
+        1,    8,    8,    9,    8,   10,   11,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,   12,   13,   14,
+       15,   16,    1,   17,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+       18,   19,   20,    1,    8,    1,    8,    8,    8,    8,
+
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,   21,   22,   23,   24,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -435,98 +470,86 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[40] =
+static yyconst flex_int32_t yy_meta[25] =
     {   0,
-        1,    1,    2,    1,    3,    4,    1,    4,    1,    1,
-        1,    1,    1,    4,    4,    4,    4,    4,    1,    1,
-        1,    1,    4,    4,    4,    4,    1,    5,    1,    4,
-        4,    4,    4,    4,    4,    4,    1,    1,    1
+        1,    1,    1,    1,    2,    3,    2,    2,    1,    1,
+        1,    1,    1,    1,    2,    1,    2,    1,    4,    1,
+        1,    1,    1,    2
     } ;
 
-static yyconst flex_int16_t yy_base[70] =
+static yyconst flex_int16_t yy_base[49] =
     {   0,
-        0,    0,   35,   36,   94,   95,   40,   72,   95,   21,
-        0,   95,   95,   95,   95,   95,   95,   71,   52,   69,
-       95,   95,   95,   95,   95,    0,   95,    0,   46,   95,
-       53,   56,   54,   61,    0,   95,   95,   95,    0,   95,
-       50,   50,   48,   49,   50,   47,   36,   39,   95,   27,
-       43,   45,   37,   38,   95,   95,   41,   43,   42,   38,
-       95,   95,   95,   95,   95,   64,   66,   71,   75
+        0,    0,   19,   20,   54,   58,   45,   24,   26,   31,
+       58,   30,   58,   58,   58,   58,   58,   17,   29,   18,
+       28,   58,   58,   58,   58,   58,   27,    0,   58,   29,
+       39,   33,   25,   58,   58,   58,   58,   58,   58,   58,
+       58,    0,   58,   58,   58,   48,   51,   55
     } ;
 
-static yyconst flex_int16_t yy_def[70] =
+static yyconst flex_int16_t yy_def[49] =
     {   0,
-       65,    1,   66,   66,   65,   65,   65,   65,   65,   65,
-       67,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   68,   65,   69,   65,   65,
-       65,   65,   65,   65,   67,   65,   65,   65,   68,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,    0,   65,   65,   65,   65
+       45,    1,   46,   46,   45,   45,   45,   45,   45,   47,
+       45,   47,   45,   45,   45,   45,   45,   45,   45,   45,
+       47,   45,   45,   45,   45,   45,   47,   48,   45,   45,
+       45,   45,   47,   45,   45,   45,   45,   45,   45,   45,
+       45,   48,   45,   45,    0,   45,   45,   45
     } ;
 
-static yyconst flex_int16_t yy_nxt[135] =
+static yyconst flex_int16_t yy_nxt[83] =
     {   0,
-        6,    7,    7,    8,    9,    6,   10,   11,   12,   13,
-       14,   15,   16,   11,   11,   11,   11,   11,   17,   18,
-       19,   20,   11,   11,   11,   11,   21,   11,   22,   11,
-       11,   11,   11,   11,   11,   11,   23,   24,   25,   27,
-       27,   29,   29,   31,   32,   33,   34,   29,   29,   51,
-       57,   52,   58,   59,   64,   60,   63,   62,   61,   56,
-       55,   54,   28,   28,   26,   26,   26,   26,   26,   35,
-       35,   39,   39,   53,   39,   40,   50,   40,   40,   40,
-       49,   48,   47,   46,   45,   44,   43,   42,   41,   38,
-       37,   36,   30,   65,    5,   65,   65,   65,   65,   65,
-
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65
+        6,    7,    8,    9,   10,   11,    6,   12,   13,   14,
+       15,   16,   17,   18,   19,   20,   21,   22,   12,   23,
+       24,   25,   26,   27,   29,   29,   32,   32,   32,   32,
+       35,   36,   38,   39,   43,   32,   32,   30,   30,   45,
+       31,   41,   40,   37,   45,   34,   31,   44,   28,   28,
+       28,   28,   33,   45,   33,   42,   42,    5,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45
     } ;
 
-static yyconst flex_int16_t yy_chk[135] =
+static yyconst flex_int16_t yy_chk[83] =
     {   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,    3,
-        4,    7,    7,   10,   10,   10,   10,   29,   29,   47,
-       53,   47,   53,   54,   60,   54,   59,   58,   57,   52,
-       51,   50,    3,    4,   66,   66,   66,   66,   66,   67,
-       67,   68,   68,   48,   68,   69,   46,   69,   69,   69,
-       45,   44,   43,   42,   41,   34,   33,   32,   31,   20,
-       19,   18,    8,    5,   65,   65,   65,   65,   65,   65,
-
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65
+        1,    1,    1,    1,    3,    4,    8,    8,    9,    9,
+       18,   18,   20,   20,   30,   32,   32,    3,    4,   33,
+       31,   27,   21,   19,   12,   10,    7,   30,   46,   46,
+       46,   46,   47,    5,   47,   48,   48,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45
     } ;
 
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[33] =
+    {   0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,     };
 
-extern int ce_expr_flex_debug;
-int ce_expr_flex_debug = 0;
+static yyconst flex_int16_t yy_rule_linenum[32] =
+    {   0,
+       94,   95,   96,   97,   98,   99,  100,  101,  102,  103,
+      104,  106,  107,  108,  109,  110,  111,  112,  113,  114,
+      115,  117,  119,  121,  125,  127,  129,  131,  133,  140,
+      152
+    } ;
 
 /* 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"
+#line 1 "d4_ce_scanner.ll"
 /*
  -*- 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.
+ Copyright (c) 2013 OPeNDAP, Inc.
  Author: James Gallagher <jgallagher at opendap.org>
 
  This library is free software; you can redistribute it and/or
@@ -544,76 +567,45 @@ char *ce_exprtext;
  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).
+#line 29 "d4_ce_scanner.ll"
+//#include "config.h"
 
-  jhrg 9/5/95
-*/
-#line 48 "ce_expr.lex"
-
-#include "config.h"
-
-static char rcsid[] not_used = {"$Id: ce_expr.lex 27157 2013-09-28 21:22:52Z 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); /* see das.lex */ \
-}
-
-#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);
-
-#define YY_NO_INPUT 1
-
-/* 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 617 "lex.ce_expr.cc"
+#include "D4CEScanner.h"
+
+/* typedef to make the returns for the tokens shorter */
+typedef libdap::D4CEParser::token token;
+
+/* This was added because of some notes on the net about compiler version
+   issues. I don't know if it's needed when using the C++ mode of flex. */
+#undef yywrap
+#define yywrap() 1
+
+/* define yyterminate as this instead of NULL */
+#define yyterminate() return(token::END)
+
+/* Use this if several scanners are needed. This will cause flex to
+   #define yyFlexLexer to be <prefix>FlexLexer (the yyFlexLexer is defined
+   in lex.<prefix>.cc. jhrg 8/8/13 */
+/* These two options turn on line counting - useful for error messages - 
+   and debugging, respectively. When debugging is on, it's possible to see
+   which scanner rules are used at which points in the input. */
+/* Do not output the default rule (where any unmatched input is echoed to 
+   stdout). When set, nodefault will cause the scanner to exit on an error. */
+/* noyywrap makes the scanner assume that EOF/EOS is the end of the input.
+   If this is not set, the scanner will assume there are more files to 
+   scan. */ 
+/* When set, warn prints a message when the default rule can be matched
+   but nodefault is given (among other warnings). */
+
+/* This pattern just ensures that a word does not start with '#' which
+   is the DAP2 comment character. */
+#line 83 "d4_ce_scanner.ll"
+// Code run each time a pattern is matched
+#define YY_USER_ACTION loc->columns(yyleng);
+#line 609 "lex.d4_ce.cc"
 
 #define INITIAL 0
 #define quote 1
@@ -623,55 +615,31 @@ static void store_op(int op);
  * 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.
  */
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
 #include <unistd.h>
+/* %endif */
 #endif
 
 #ifndef YY_EXTRA_TYPE
 #define YY_EXTRA_TYPE void *
 #endif
 
-static int yy_init_globals (void );
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
+/* %if-c-only Reentrant structure and macros (non-C++). */
+/* %if-reentrant */
+/* %if-c-only */
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif End reentrant structures and macros. */
+/* %if-bison-bridge */
+/* %endif */
+/* %not-for-header */
 
-int ce_exprlex_destroy (void );
+/* %ok-for-header */
 
-int ce_exprget_debug (void );
-
-void ce_exprset_debug (int debug_flag  );
-
-YY_EXTRA_TYPE ce_exprget_extra (void );
-
-void ce_exprset_extra (YY_EXTRA_TYPE user_defined  );
-
-FILE *ce_exprget_in (void );
-
-void ce_exprset_in  (FILE * in_str  );
-
-FILE *ce_exprget_out (void );
-
-void ce_exprset_out  (FILE * out_str  );
-
-int ce_exprget_leng (void );
-
-char *ce_exprget_text (void );
-
-int ce_exprget_lineno (void );
-
-void ce_exprset_lineno (int line_number  );
-
-/* 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
+/* %endif */
 
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char *,yyconst char *,int );
@@ -682,15 +650,17 @@ static int yy_flex_strlen (yyconst char * );
 #endif
 
 #ifndef YY_NO_INPUT
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
 
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
+/* %ok-for-header */
 
+/* %endif */
 #endif
 
+/* %if-c-only */
+/* %endif */
+
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
 #define YY_READ_BUF_SIZE 8192
@@ -698,10 +668,11 @@ static int input (void );
 
 /* 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 do { if (fwrite( ce_exprtext, ce_exprleng, 1, ce_exprout )) {} } while (0)
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
+/* %if-c++-only C++ definition */
+#define ECHO LexerOutput( yytext, yyleng )
+/* %endif */
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -709,34 +680,12 @@ static int input (void );
  */
 #ifndef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-		{ \
-		int c = '*'; \
-		unsigned 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); \
-			} \
-		}\
+/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\
 \
+/* %if-c++-only C++ definition \ */\
+	if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+/* %endif */
 
 #endif
 
@@ -755,23 +704,39 @@ static int input (void );
 
 /* Report a fatal error. */
 #ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+#define YY_FATAL_ERROR(msg) LexerError( msg )
+/* %endif */
 #endif
 
+/* %if-tables-serialization structures and prototypes */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* %tables-yydmap generated elements */
+/* %endif */
 /* end tables serialization structures and prototypes */
 
+/* %ok-for-header */
+
 /* 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)
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
+/* %if-c++-only C++ definition */
+#define YY_DECL int yyFlexLexer::yylex()
+/* %endif */
 #endif /* !YY_DECL */
 
-/* Code executed at the beginning of each rule, after ce_exprtext and ce_exprleng
+/* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
  */
 #ifndef YY_USER_ACTION
@@ -783,9 +748,12 @@ extern int ce_exprlex (void);
 #define YY_BREAK break;
 #endif
 
+/* %% [6.0] YY_RULE_SETUP definition goes here */
 #define YY_RULE_SETUP \
 	YY_USER_ACTION
 
+/* %not-for-header */
+
 /** The main scanner function which does all the work.
  */
 YY_DECL
@@ -794,10 +762,16 @@ YY_DECL
 	register char *yy_cp, *yy_bp;
 	register int yy_act;
     
-#line 132 "ce_expr.lex"
+/* %% [7.0] user's declarations go here */
+#line 87 "d4_ce_scanner.ll"
 
 
-#line 801 "lex.ce_expr.cc"
+
+// Code run each time yylex is called
+loc->step();
+
+
+#line 775 "lex.d4_ce.cc"
 
 	if ( !(yy_init) )
 		{
@@ -810,23 +784,32 @@ YY_DECL
 		if ( ! (yy_start) )
 			(yy_start) = 1;	/* first start state */
 
-		if ( ! ce_exprin )
-			ce_exprin = stdin;
+		if ( ! yyin )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+			yyin = & std::cin;
+/* %endif */
 
-		if ( ! ce_exprout )
-			ce_exprout = stdout;
+		if ( ! yyout )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+			yyout = & std::cout;
+/* %endif */
 
 		if ( ! YY_CURRENT_BUFFER ) {
-			ce_exprensure_buffer_stack ();
+			yyensure_buffer_stack ();
 			YY_CURRENT_BUFFER_LVALUE =
-				ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+				yy_create_buffer( yyin, YY_BUF_SIZE );
 		}
 
-		ce_expr_load_buffer_state( );
+		yy_load_buffer_state(  );
 		}
 
 	while ( 1 )		/* loops until end-of-file is reached */
 		{
+/* %% [8.0] yymore()-related code goes here */
 		(yy_more_len) = 0;
 		if ( (yy_more_flag) )
 			{
@@ -835,7 +818,7 @@ YY_DECL
 			}
 		yy_cp = (yy_c_buf_p);
 
-		/* Support of ce_exprtext. */
+		/* Support of yytext. */
 		*yy_cp = (yy_hold_char);
 
 		/* yy_bp points to the position in yy_ch_buf of the start of
@@ -843,6 +826,7 @@ YY_DECL
 		 */
 		yy_bp = yy_cp;
 
+/* %% [9.0] code to set up and find next match goes here */
 		yy_current_state = (yy_start);
 yy_match:
 		do
@@ -856,29 +840,55 @@ yy_match:
 			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 >= 66 )
+				if ( yy_current_state >= 46 )
 					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] != 95 );
+		while ( yy_current_state != 45 );
+		yy_cp = (yy_last_accepting_cpos);
+		yy_current_state = (yy_last_accepting_state);
 
 yy_find_action:
+/* %% [10.0] code to find the action number goes here */
 		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;
 
+/* %% [11.0] code for yylineno update goes here */
+
+		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+			{
+			yy_size_t yyl;
+			for ( yyl = (yy_more_len); yyl < yyleng; ++yyl )
+				if ( yytext[yyl] == '\n' )
+					   
+    yylineno++;
+;
+			}
+
 do_action:	/* This label is used only to access EOF actions. */
 
+/* %% [12.0] debug code goes here */
+		if ( yy_flex_debug )
+			{
+			if ( yy_act == 0 )
+				std::cerr << "--scanner backing up\n";
+			else if ( yy_act < 32 )
+				std::cerr << "--accepting rule at line " << yy_rule_linenum[yy_act] <<
+				         "(\"" << yytext << "\")\n";
+			else if ( yy_act == 32 )
+				std::cerr << "--accepting default rule (\"" << yytext << "\")\n";
+			else if ( yy_act == 33 )
+				std::cerr << "--(end of buffer or a NUL)\n";
+			else
+				std::cerr << "--EOF (start condition " << YY_START << ")\n";
+			}
+
 		switch ( yy_act )
 	{ /* beginning of action switch */
+/* %% [13.0] actions go here */
 			case 0: /* must back up */
 			/* undo the effects of YY_DO_BEFORE_ACTION */
 			*yy_cp = (yy_hold_char);
@@ -888,190 +898,193 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 134 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 94 "d4_ce_scanner.ll"
+return token::LBRACKET;
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 135 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 95 "d4_ce_scanner.ll"
+return token::RBRACKET;
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 136 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 96 "d4_ce_scanner.ll"
+return token::COLON;
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 137 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 97 "d4_ce_scanner.ll"
+return token::COMMA;
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 138 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 98 "d4_ce_scanner.ll"
+return token::SEMICOLON;
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 139 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 99 "d4_ce_scanner.ll"
+return token::PIPE;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 140 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 100 "d4_ce_scanner.ll"
+return token::LBRACE;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 141 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 101 "d4_ce_scanner.ll"
+return token::RBRACE;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 142 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 102 "d4_ce_scanner.ll"
+return token::GROUP_SEP;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 144 "ce_expr.lex"
-store_id(); return SCAN_WORD;
+#line 103 "d4_ce_scanner.ll"
+return token::PATH_SEP;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 146 "ce_expr.lex"
-store_op(SCAN_EQUAL); return SCAN_EQUAL;
+#line 104 "d4_ce_scanner.ll"
+return token::ASSIGN;
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 147 "ce_expr.lex"
-store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
+#line 106 "d4_ce_scanner.ll"
+return token::EQUAL;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 148 "ce_expr.lex"
-store_op(SCAN_GREATER); return SCAN_GREATER;
+#line 107 "d4_ce_scanner.ll"
+return token::NOT_EQUAL;
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 149 "ce_expr.lex"
-store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
+#line 108 "d4_ce_scanner.ll"
+return token::GREATER;
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 150 "ce_expr.lex"
-store_op(SCAN_LESS); return SCAN_LESS;
+#line 109 "d4_ce_scanner.ll"
+return token::GREATER_EQUAL;
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 151 "ce_expr.lex"
-store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
+#line 110 "d4_ce_scanner.ll"
+return token::LESS;
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 152 "ce_expr.lex"
-store_op(SCAN_REGEXP); return SCAN_REGEXP;
+#line 111 "d4_ce_scanner.ll"
+return token::LESS_EQUAL;
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 154 "ce_expr.lex"
-store_op(SCAN_STAR); return SCAN_STAR;
+#line 112 "d4_ce_scanner.ll"
+return token::REGEX_MATCH;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 156 "ce_expr.lex"
-return SCAN_HASH_BYTE;
+#line 113 "d4_ce_scanner.ll"
+return token::LESS_BBOX;
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 157 "ce_expr.lex"
-return SCAN_HASH_INT16;
+#line 114 "d4_ce_scanner.ll"
+return token::GREATER_BBOX;
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 158 "ce_expr.lex"
-return SCAN_HASH_UINT16;
+#line 115 "d4_ce_scanner.ll"
+return token::MASK;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 159 "ce_expr.lex"
-return SCAN_HASH_INT32;
+#line 117 "d4_ce_scanner.ll"
+/* ignore these */
 	YY_BREAK
 case 23:
+/* rule 23 can match eol */
 YY_RULE_SETUP
-#line 160 "ce_expr.lex"
-return SCAN_HASH_UINT32;
+#line 119 "d4_ce_scanner.ll"
+/* ignore these */
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 161 "ce_expr.lex"
-return SCAN_HASH_FLOAT32;
+#line 121 "d4_ce_scanner.ll"
+{ yylval->build<std::string>(yytext); return token::WORD; }
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 123 "d4_ce_scanner.ll"
+return token::END;
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 162 "ce_expr.lex"
-return SCAN_HASH_FLOAT64;
+#line 125 "d4_ce_scanner.ll"
+{ BEGIN(quote); yymore(); }
 	YY_BREAK
 case 26:
 /* rule 26 can match eol */
 YY_RULE_SETUP
-#line 164 "ce_expr.lex"
-
-	YY_BREAK
-case YY_STATE_EOF(INITIAL):
-#line 165 "ce_expr.lex"
-yy_init = 1; yyterminate();
+#line 127 "d4_ce_scanner.ll"
+yymore(); /* Anything that's not a double quote or a backslash */
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 167 "ce_expr.lex"
-BEGIN(quote); yymore();
+#line 129 "d4_ce_scanner.ll"
+yymore(); /* This matches the escaped double quote (\") */
 	YY_BREAK
 case 28:
-/* rule 28 can match eol */
 YY_RULE_SETUP
-#line 169 "ce_expr.lex"
-yymore(); /*"*/
+#line 131 "d4_ce_scanner.ll"
+yymore(); /* This matches an escaped escape (\\) */
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 171 "ce_expr.lex"
-yymore();
+#line 133 "d4_ce_scanner.ll"
+{
+                    BEGIN(INITIAL);
+                    if (yytext) {
+                        YY_FATAL_ERROR("Inside a string, backslash (\\) can escape a double quote or must itself be escaped (\\\\).");
+                    }
+                }
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 173 "ce_expr.lex"
+#line 140 "d4_ce_scanner.ll"
 { 
-    		  BEGIN(INITIAL); 
-              store_str();
-              return SCAN_STR;
+                /* An unescaped double quote in the 'quote' state indicates the end of the string */
+                BEGIN(INITIAL); 
+                yylval->build<std::string>(yytext); 
+                return token::STRING;
             }
 	YY_BREAK
 case YY_STATE_EOF(quote):
-#line 179 "ce_expr.lex"
+#line 147 "d4_ce_scanner.ll"
 {
                   BEGIN(INITIAL);   /* resetting the state is needed for reentrant parsers */
-                  char msg[256];
-                  sprintf(msg, "Unterminated quote\n");
-                  YY_FATAL_ERROR(msg);
+                  YY_FATAL_ERROR("Unterminated quote");
                 }
 	YY_BREAK
 case 31:
-/* rule 31 can match eol */
 YY_RULE_SETUP
-#line 186 "ce_expr.lex"
+#line 152 "d4_ce_scanner.ll"
 {
-                  if (ce_exprtext) {	/* suppress msgs about `' chars */
-                    fprintf(stderr, "Character `%c' is not", *ce_exprtext);
-                    fprintf(stderr, " allowed and has been ignored\n");
-                  }
-		        }
+        BEGIN(INITIAL);
+        if (yytext) {
+            YY_FATAL_ERROR("Characters found in the input were not recognized.");
+        }
+    }
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 192 "ce_expr.lex"
-ECHO;
+#line 158 "d4_ce_scanner.ll"
+YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 1075 "lex.ce_expr.cc"
+#line 1088 "lex.d4_ce.cc"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1086,15 +1099,15 @@ ECHO;
 			{
 			/* 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
+			 * just pointed yyin at a new source and called
+			 * yylex().  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_input_file = yyin;
 			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
 			}
 
@@ -1136,7 +1149,9 @@ ECHO;
 
 			else
 				{
-				yy_cp = (yy_c_buf_p);
+/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
+				yy_cp = (yy_last_accepting_cpos);
+				yy_current_state = (yy_last_accepting_state);
 				goto yy_find_action;
 				}
 			}
@@ -1147,11 +1162,11 @@ ECHO;
 				{
 				(yy_did_buffer_switch_on_eof) = 0;
 
-				if ( ce_exprwrap( ) )
+				if ( yywrap(  ) )
 					{
 					/* Note: because we've taken care in
 					 * yy_get_next_buffer() to have set up
-					 * ce_exprtext, we can now set up
+					 * yytext, 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
@@ -1200,7 +1215,103 @@ ECHO;
 			"fatal flex scanner internal error--no action found" );
 	} /* end of action switch */
 		} /* end of scanning one token */
-} /* end of ce_exprlex */
+} /* end of yylex */
+/* %ok-for-header */
+
+/* %if-c++-only */
+/* %not-for-header */
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout )
+{
+	yyin = arg_yyin;
+	yyout = arg_yyout;
+	yy_c_buf_p = 0;
+	yy_init = 0;
+	yy_start = 0;
+	yy_flex_debug = 0;
+	yylineno = 1;	// this will only get updated if %option yylineno
+
+	yy_did_buffer_switch_on_eof = 0;
+
+	yy_looking_for_trail_begin = 0;
+	yy_more_flag = 0;
+	yy_more_len = 0;
+	yy_more_offset = yy_prev_more_offset = 0;
+
+	yy_start_stack_ptr = yy_start_stack_depth = 0;
+	yy_start_stack = NULL;
+
+	yy_buffer_stack = 0;
+	yy_buffer_stack_top = 0;
+	yy_buffer_stack_max = 0;
+
+	yy_state_buf = 0;
+
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::~yyFlexLexer()
+{
+	delete [] yy_state_buf;
+	d4_cefree(yy_start_stack  );
+	yy_delete_buffer( YY_CURRENT_BUFFER );
+	d4_cefree(yy_buffer_stack  );
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out )
+{
+	if ( new_in )
+		{
+		yy_delete_buffer( YY_CURRENT_BUFFER );
+		yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE  ) );
+		}
+
+	if ( new_out )
+		yyout = new_out;
+}
+
+#ifdef YY_INTERACTIVE
+size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ )
+#else
+size_t yyFlexLexer::LexerInput( char* buf, size_t max_size )
+#endif
+{
+	if ( yyin->eof() || yyin->fail() )
+		return 0;
+
+#ifdef YY_INTERACTIVE
+	yyin->get( buf[0] );
+
+	if ( yyin->eof() )
+		return 0;
+
+	if ( yyin->bad() )
+		return -1;
+
+	return 1;
+
+#else
+	(void) yyin->read( buf, max_size );
+
+	if ( yyin->bad() )
+		return -1;
+	else
+		return yyin->gcount();
+#endif
+}
+
+void yyFlexLexer::LexerOutput( const char* buf, size_t size )
+{
+	(void) yyout->write( buf, size );
+}
+/* %ok-for-header */
+
+/* %endif */
 
 /* yy_get_next_buffer - try to read in a new buffer
  *
@@ -1209,7 +1320,11 @@ ECHO;
  *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  *	EOB_ACT_END_OF_FILE - end of file
  */
-static int yy_get_next_buffer (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+int yyFlexLexer::yy_get_next_buffer()
+/* %endif */
 {
     	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
 	register char *source = (yytext_ptr);
@@ -1255,7 +1370,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1269,7 +1384,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1278,7 +1393,7 @@ static int yy_get_next_buffer (void)
 
 				b->yy_ch_buf = (char *)
 					/* Include room in for 2 EOB chars. */
-					ce_exprrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+					d4_cerealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
 				}
 			else
 				/* Can't grow it, we don't own it. */
@@ -1300,7 +1415,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1310,7 +1425,7 @@ static int yy_get_next_buffer (void)
 		if ( number_to_move == YY_MORE_ADJ )
 			{
 			ret_val = EOB_ACT_END_OF_FILE;
-			ce_exprrestart(ce_exprin  );
+			yyrestart( yyin  );
 			}
 
 		else
@@ -1327,7 +1442,7 @@ static int yy_get_next_buffer (void)
 	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ce_exprrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) d4_cerealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
 	}
@@ -1343,15 +1458,23 @@ static int yy_get_next_buffer (void)
 
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
-    static yy_state_type yy_get_previous_state (void)
+/* %if-c-only */
+/* %not-for-header */
+
+/* %endif */
+/* %if-c++-only */
+    yy_state_type yyFlexLexer::yy_get_previous_state()
+/* %endif */
 {
 	register yy_state_type yy_current_state;
 	register char *yy_cp;
     
+/* %% [15.0] code to get the start state into yy_current_state goes here */
 	yy_current_state = (yy_start);
 
 	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
 		{
+/* %% [16.0] code to find the next state goes here */
 		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
 		if ( yy_accept[yy_current_state] )
 			{
@@ -1361,7 +1484,7 @@ static int yy_get_next_buffer (void)
 		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 >= 66 )
+			if ( yy_current_state >= 46 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1375,10 +1498,15 @@ static int yy_get_next_buffer (void)
  * synopsis
  *	next_state = yy_try_NUL_trans( current_state );
  */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state )
+/* %endif */
 {
 	register int yy_is_jam;
-    	register char *yy_cp = (yy_c_buf_p);
+    /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */
+	register char *yy_cp = (yy_c_buf_p);
 
 	register YY_CHAR yy_c = 1;
 	if ( yy_accept[yy_current_state] )
@@ -1389,22 +1517,69 @@ static int yy_get_next_buffer (void)
 	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 >= 66 )
+		if ( yy_current_state >= 46 )
 			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 == 65);
+	yy_is_jam = (yy_current_state == 45);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
 
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yyunput( int c, register char* yy_bp)
+/* %endif */
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up yytext */
+	*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 yy_size_t 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;
 
+/* %% [18.0] update yylineno here */
+
+    if ( c == '\n' ){
+        --yylineno;
+    }
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+/* %if-c-only */
+/* %endif */
+
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    int yyFlexLexer::yyinput()
+/* %endif */
 {
 	int c;
     
@@ -1422,7 +1597,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1439,14 +1614,14 @@ static int yy_get_next_buffer (void)
 					 */
 
 					/* Reset buffer status. */
-					ce_exprrestart(ce_exprin );
+					yyrestart( yyin );
 
 					/*FALLTHROUGH*/
 
 				case EOB_ACT_END_OF_FILE:
 					{
-					if ( ce_exprwrap( ) )
-						return EOF;
+					if ( yywrap(  ) )
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1465,44 +1640,59 @@ static int yy_get_next_buffer (void)
 		}
 
 	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve ce_exprtext */
+	*(yy_c_buf_p) = '\0';	/* preserve yytext */
 	(yy_hold_char) = *++(yy_c_buf_p);
 
+/* %% [19.0] update BOL and yylineno */
+	if ( c == '\n' )
+		   
+    yylineno++;
+;
+
 	return c;
 }
-#endif	/* ifndef YY_NO_INPUT */
+/* %if-c-only */
+/* %endif */
 
 /** 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-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yyrestart( std::istream* input_file )
+/* %endif */
 {
     
 	if ( ! YY_CURRENT_BUFFER ){
-        ce_exprensure_buffer_stack ();
+        yyensure_buffer_stack ();
 		YY_CURRENT_BUFFER_LVALUE =
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+            yy_create_buffer( yyin, YY_BUF_SIZE );
 	}
 
-	ce_expr_init_buffer(YY_CURRENT_BUFFER,input_file );
-	ce_expr_load_buffer_state( );
+	yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+	yy_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 )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+/* %endif */
 {
     
 	/* TODO. We should be able to replace this entire function body
 	 * with
-	 *		ce_exprpop_buffer_state();
-	 *		ce_exprpush_buffer_state(new_buffer);
+	 *		yypop_buffer_state();
+	 *		yypush_buffer_state(new_buffer);
      */
-	ce_exprensure_buffer_stack ();
+	yyensure_buffer_stack ();
 	if ( YY_CURRENT_BUFFER == new_buffer )
 		return;
 
@@ -1515,21 +1705,25 @@ static int yy_get_next_buffer (void)
 		}
 
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	ce_expr_load_buffer_state( );
+	yy_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
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() 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)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_load_buffer_state()
+/* %endif */
 {
     	(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;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
 	(yy_hold_char) = *(yy_c_buf_p);
 }
 
@@ -1539,35 +1733,43 @@ static void ce_expr_load_buffer_state  (void)
  * 
  * @return the allocated buffer state.
  */
-    YY_BUFFER_STATE ce_expr_create_buffer  (FILE * file, int  size )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size )
+/* %endif */
 {
 	YY_BUFFER_STATE b;
     
-	b = (YY_BUFFER_STATE) ce_expralloc(sizeof( struct yy_buffer_state )  );
+	b = (YY_BUFFER_STATE) d4_cealloc(sizeof( struct yy_buffer_state )  );
 	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_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  );
+	b->yy_ch_buf = (char *) d4_cealloc(b->yy_buf_size + 2  );
 	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
 	b->yy_is_our_buffer = 1;
 
-	ce_expr_init_buffer(b,file );
+	yy_init_buffer( b, file );
 
 	return b;
 }
 
 /** Destroy the buffer.
- * @param b a buffer created with ce_expr_create_buffer()
+ * @param b a buffer created with yy_create_buffer()
  * 
  */
-    void ce_expr_delete_buffer (YY_BUFFER_STATE  b )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b )
+/* %endif */
 {
     
 	if ( ! b )
@@ -1577,31 +1779,40 @@ static void ce_expr_load_buffer_state  (void)
 		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
 
 	if ( b->yy_is_our_buffer )
-		ce_exprfree((void *) b->yy_ch_buf  );
+		d4_cefree((void *) b->yy_ch_buf  );
 
-	ce_exprfree((void *) b  );
+	d4_cefree((void *) b  );
 }
 
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
+/* %if-c-only */
+/* %endif */
+
+/* %if-c++-only */
+
+extern "C" int isatty (int );
+
+/* %endif */
+
 /* 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.
+ * such as during a yyrestart() or at EOF.
  */
-    static void ce_expr_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file )
+/* %endif */
 
 {
 	int oerrno = errno;
     
-	ce_expr_flush_buffer(b );
+	yy_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.
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
      * In that case, we don't want to reset the lineno or column.
      */
     if (b != YY_CURRENT_BUFFER){
@@ -1609,8 +1820,11 @@ extern int isatty (int );
         b->yy_bs_column = 0;
     }
 
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+	b->yy_is_interactive = 0;
+/* %endif */
 	errno = oerrno;
 }
 
@@ -1618,7 +1832,11 @@ extern int isatty (int );
  * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
  * 
  */
-    void ce_expr_flush_buffer (YY_BUFFER_STATE  b )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b )
+/* %endif */
 {
     	if ( ! b )
 		return;
@@ -1638,23 +1856,28 @@ extern int isatty (int );
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
 	if ( b == YY_CURRENT_BUFFER )
-		ce_expr_load_buffer_state( );
+		yy_load_buffer_state(  );
 }
 
+/* %if-c-or-c++ */
 /** 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-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer)
+/* %endif */
 {
     	if (new_buffer == NULL)
 		return;
 
-	ce_exprensure_buffer_stack();
+	yyensure_buffer_stack();
 
-	/* This block is copied from ce_expr_switch_to_buffer. */
+	/* This block is copied from yy_switch_to_buffer. */
 	if ( YY_CURRENT_BUFFER )
 		{
 		/* Flush out information for old buffer. */
@@ -1668,37 +1891,49 @@ void ce_exprpush_buffer_state (YY_BUFFER_STATE new_buffer )
 		(yy_buffer_stack_top)++;
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
 
-	/* copied from ce_expr_switch_to_buffer. */
-	ce_expr_load_buffer_state( );
+	/* copied from yy_switch_to_buffer. */
+	yy_load_buffer_state(  );
 	(yy_did_buffer_switch_on_eof) = 1;
 }
+/* %endif */
 
+/* %if-c-or-c++ */
 /** Removes and deletes the top of the stack, if present.
  *  The next element becomes the new top.
  *  
  */
-void ce_exprpop_buffer_state (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yypop_buffer_state (void)
+/* %endif */
 {
     	if (!YY_CURRENT_BUFFER)
 		return;
 
-	ce_expr_delete_buffer(YY_CURRENT_BUFFER );
+	yy_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_load_buffer_state(  );
 		(yy_did_buffer_switch_on_eof) = 1;
 	}
 }
+/* %endif */
 
+/* %if-c-or-c++ */
 /* Allocates the stack if it does not exist.
  *  Guarantees space for at least one push.
  */
-static void ce_exprensure_buffer_stack (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yyensure_buffer_stack(void)
+/* %endif */
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1707,11 +1942,11 @@ static void ce_exprensure_buffer_stack (void)
 		 * immediate realloc on the next call.
          */
 		num_to_alloc = 1;
-		(yy_buffer_stack) = (struct yy_buffer_state**)ce_expralloc
+		(yy_buffer_stack) = (struct yy_buffer_state**)d4_cealloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ce_exprensure_buffer_stack()" );
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 								  
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 				
@@ -1726,114 +1961,91 @@ static void ce_exprensure_buffer_stack (void)
 		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) = (struct yy_buffer_state**)d4_cerealloc
 								((yy_buffer_stack),
 								num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ce_exprensure_buffer_stack()" );
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 
 		/* 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;
 	}
 }
+/* %endif */
 
-/** 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;
+/* %if-c-only */
+/* %endif */
 
-	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()" );
+/* %if-c-only */
+/* %endif */
 
-	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;
+/* %if-c-only */
+/* %endif */
 
-	ce_expr_switch_to_buffer(b  );
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_push_state( int new_state )
+/* %endif */
+{
+    	if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) )
+		{
+		yy_size_t new_size;
 
-	return b;
-}
+		(yy_start_stack_depth) += YY_START_STACK_INCR;
+		new_size = (yy_start_stack_depth) * sizeof( int );
 
-/** 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 yystr 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) );
-}
+		if ( ! (yy_start_stack) )
+			(yy_start_stack) = (int *) d4_cealloc(new_size  );
 
-/** 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()" );
+		else
+			(yy_start_stack) = (int *) d4_cerealloc((void *) (yy_start_stack),new_size  );
 
-	for ( i = 0; i < _yybytes_len; ++i )
-		buf[i] = yybytes[i];
+		if ( ! (yy_start_stack) )
+			YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+		}
 
-	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+	(yy_start_stack)[(yy_start_stack_ptr)++] = YY_START;
 
-	b = ce_expr_scan_buffer(buf,n );
-	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in ce_expr_scan_bytes()" );
+	BEGIN(new_state);
+}
 
-	/* It's okay to grow etc. this buffer, and we should throw it
-	 * away when we're done.
-	 */
-	b->yy_is_our_buffer = 1;
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_pop_state()
+/* %endif */
+{
+    	if ( --(yy_start_stack_ptr) < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
 
-	return b;
+	BEGIN((yy_start_stack)[(yy_start_stack_ptr)]);
+}
+
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    int yyFlexLexer::yy_top_state()
+/* %endif */
+{
+    	return (yy_start_stack)[(yy_start_stack_ptr) - 1];
 }
 
 #ifndef YY_EXIT_FAILURE
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yy_fatal_error (yyconst char* msg )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::LexerError( yyconst char msg[] )
 {
-    	(void) fprintf( stderr, "%s\n", msg );
+    	std::cerr << msg << std::endl;
 	exit( YY_EXIT_FAILURE );
 }
+/* %endif */
 
 /* Redefine yyless() so it works in section 3 code. */
 
@@ -1841,146 +2053,38 @@ static void yy_fatal_error (yyconst char* msg )
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ce_exprtext. */ \
+		/* Undo effects of setting up yytext. */ \
         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; \
+		yytext[yyleng] = (yy_hold_char); \
+		(yy_c_buf_p) = yytext + yyless_macro_arg; \
 		(yy_hold_char) = *(yy_c_buf_p); \
 		*(yy_c_buf_p) = '\0'; \
-		ce_exprleng = yyless_macro_arg; \
+		yyleng = 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;
-}
+/* %if-c-only */
+/* %if-reentrant */
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif */
 
-/** Get the length of the current token.
- * 
- */
-int ce_exprget_leng  (void)
-{
-        return ce_exprleng;
-}
+/* %if-reentrant */
+/* %if-bison-bridge */
+/* %endif */
+/* %endif if-c-only */
 
-/** Get the current token.
- * 
- */
-
-char *ce_exprget_text  (void)
-{
-        return ce_exprtext;
-}
+/* %if-c-only */
+/* %endif */
 
-/** 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;
-}
+/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
+/* %if-reentrant */
+/* %endif */
+/* %endif */
 
 /*
  * Internal utility routines.
@@ -2006,12 +2110,12 @@ static int yy_flex_strlen (yyconst char * s )
 }
 #endif
 
-void *ce_expralloc (yy_size_t  size )
+void *d4_cealloc (yy_size_t  size )
 {
 	return (void *) malloc( size );
 }
 
-void *ce_exprrealloc  (void * ptr, yy_size_t  size )
+void *d4_cerealloc  (void * ptr, yy_size_t  size )
 {
 	/* The cast to (char *) in the following accommodates both
 	 * implementations that use char* generic pointers, and those
@@ -2023,69 +2127,19 @@ void *ce_exprrealloc  (void * ptr, yy_size_t  size )
 	return (void *) realloc( (char *) ptr, size );
 }
 
-void ce_exprfree (void * ptr )
+void d4_cefree (void * ptr )
 {
-	free( (char *) ptr );	/* see ce_exprrealloc() for (char *) cast */
+	free( (char *) ptr );	/* see d4_cerealloc() for (char *) cast */
 }
 
+/* %if-tables-serialization definitions */
+/* %define-yytables   The name for this specific scanner's tables. */
 #define YYTABLES_NAME "yytables"
+/* %endif */
 
-#line 192 "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, ce_exprtext, ID_MAX-1);
-    ce_exprlval.id[ID_MAX-1] = '\0';
-}
+/* %ok-for-header */
 
-static void
-store_str()
-{
-    // transform %20 to a space. 7/11/2001 jhrg
-    string *s = new string(ce_exprtext); // move all calls of www2id into the parser. jhrg 7/5/13 www2id(string(ce_exprtext)));
-
-    if (*s->begin() == '\"' && *(s->end()-1) == '\"') {
-	s->erase(s->begin());
-	s->erase(s->end()-1);
-    }
+#line 158 "d4_ce_scanner.ll"
 
-    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.ce_expr.cc b/d4_ce/lex.d4_function.cc
similarity index 53%
copy from lex.ce_expr.cc
copy to d4_ce/lex.d4_function.cc
index 8d2a9d6..3f57dbc 100644
--- a/lex.ce_expr.cc
+++ b/d4_ce/lex.d4_function.cc
@@ -1,29 +1,17 @@
-#line 2 "lex.ce_expr.cc"
 
-#line 4 "lex.ce_expr.cc"
+#line 3 "lex.d4_function.cc"
 
 #define  YY_INT_ALIGNED short int
 
 /* A lexical scanner generated by flex */
 
-#define yy_create_buffer ce_expr_create_buffer
-#define yy_delete_buffer ce_expr_delete_buffer
-#define yy_flex_debug ce_expr_flex_debug
-#define yy_init_buffer ce_expr_init_buffer
-#define yy_flush_buffer ce_expr_flush_buffer
-#define yy_load_buffer_state ce_expr_load_buffer_state
-#define yy_switch_to_buffer ce_expr_switch_to_buffer
-#define yyin ce_exprin
-#define yyleng ce_exprleng
-#define yylex ce_exprlex
-#define yylineno ce_exprlineno
-#define yyout ce_exprout
-#define yyrestart ce_exprrestart
-#define yytext ce_exprtext
-#define yywrap ce_exprwrap
-#define yyalloc ce_expralloc
-#define yyrealloc ce_exprrealloc
-#define yyfree ce_exprfree
+/* %not-for-header */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+/* %endif */
+/* %endif */
+/* %ok-for-header */
 
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
@@ -33,16 +21,33 @@
 #define FLEX_BETA
 #endif
 
+/* %if-c++-only */
+    /* The c++ scanner is a mess. The FlexLexer.h header file relies on the
+     * following macro. This is required in order to pass the c++-multiple-scanners
+     * test in the regression suite. We get reports that it breaks inheritance.
+     * We will address this in a future release of flex, or omit the C++ scanner
+     * altogether.
+     */
+    #define yyFlexLexer d4_functionFlexLexer
+/* %endif */
+
+/* %if-c-only */
+/* %endif */
+
+/* %if-c-only */
+/* %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>
+/* %if-c-only */
+/* %endif */
 
+/* %if-tables-serialization */
+/* %endif */
 /* end standard C headers. */
 
+/* %if-c-or-c++ */
 /* flex integer type definitions */
 
 #ifndef FLEXINT_H
@@ -66,6 +71,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -106,6 +112,17 @@ typedef unsigned int flex_uint32_t;
 
 #endif /* ! FLEXINT_H */
 
+/* %endif */
+
+/* %if-c++-only */
+/* begin standard C++ headers. */
+#include <iostream> 
+#include <errno.h>
+#include <cstdlib>
+#include <cstring>
+/* end standard C++ headers. */
+/* %endif */
+
 #ifdef __cplusplus
 
 /* The "const" storage-class-modifier is valid. */
@@ -127,8 +144,13 @@ typedef unsigned int flex_uint32_t;
 #define yyconst
 #endif
 
+/* %not-for-header */
+
 /* Returned upon end-of-file. */
 #define YY_NULL 0
+/* %ok-for-header */
+
+/* %not-for-header */
 
 /* Promotes a possibly negative, possibly signed char to an unsigned
  * integer for use as an array index.  If the signed char is negative,
@@ -136,6 +158,14 @@ typedef unsigned int flex_uint32_t;
  * double cast.
  */
 #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+/* %ok-for-header */
+
+/* %if-reentrant */
+/* %endif */
+
+/* %if-not-reentrant */
+
+/* %endif */
 
 /* 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
@@ -154,7 +184,7 @@ typedef unsigned int flex_uint32_t;
 #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_NEW_FILE yyrestart( yyin  )
 
 #define YY_END_OF_BUFFER_CHAR 0
 
@@ -172,42 +202,65 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int ce_exprleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+/* %if-not-reentrant */
+extern yy_size_t yyleng;
+/* %endif */
 
-extern FILE *ce_exprin, *ce_exprout;
+/* %if-c-only */
+/* %if-not-reentrant */
+/* %endif */
+/* %endif */
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
 
-    #define YY_LESS_LINENO(n)
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+     *       access to the local variable yy_act. Since yyless() is a macro, it would break
+     *       existing scanners that call yyless() from OUTSIDE yylex. 
+     *       One obvious solution it to make yy_act a global. I tried that, and saw
+     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                yy_size_t yyl;\
+                for ( yyl = n; yyl < yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
     
 /* Return all but the first "n" matched characters back to the input stream. */
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ce_exprtext. */ \
+		/* Undo effects of setting up yytext. */ \
         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 */ \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
 		} \
 	while ( 0 )
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
 	{
-	FILE *yy_input_file;
+/* %if-c-only */
+/* %endif */
+
+/* %if-c++-only */
+	std::istream* yy_input_file;
+/* %endif */
 
 	char *yy_ch_buf;		/* input buffer */
 	char *yy_buf_pos;		/* current position in input buffer */
@@ -220,7 +273,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t 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
@@ -260,18 +313,22 @@ struct yy_buffer_state
 	 * 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.
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin 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. */
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+/* %if-not-reentrant */
+/* %endif */
+/* %ok-for-header */
+
+/* %endif */
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
@@ -288,51 +345,27 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
  */
 #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;
+/* %if-c-only Standard (non-C++) definition */
+/* %if-not-reentrant */
+/* %not-for-header */
 
-/* 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 */
+/* %ok-for-header */
 
-/* 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  );
+/* %endif */
+/* %endif */
 
-void *ce_expralloc (yy_size_t  );
-void *ce_exprrealloc (void *,yy_size_t  );
-void ce_exprfree (void *  );
+void *d4_functionalloc (yy_size_t  );
+void *d4_functionrealloc (void *,yy_size_t  );
+void d4_functionfree (void *  );
 
-#define yy_new_buffer ce_expr_create_buffer
+#define yy_new_buffer yy_create_buffer
 
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
-        ce_exprensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
@@ -340,51 +373,55 @@ void ce_exprfree (void *  );
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
-        ce_exprensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
 
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
+/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
 /* Begin user sect3 */
-
-#define ce_exprwrap(n) 1
 #define YY_SKIP_YYWRAP
 
-typedef unsigned char YY_CHAR;
+#define FLEX_DEBUG
 
-FILE *ce_exprin = (FILE *) 0, *ce_exprout = (FILE *) 0;
+typedef unsigned char YY_CHAR;
 
-typedef int yy_state_type;
+#define yytext_ptr yytext
 
-extern int ce_exprlineno;
+#include <FlexLexer.h>
 
-int ce_exprlineno = 1;
+int yyFlexLexer::yywrap() { return 1; }
+int yyFlexLexer::yylex()
+	{
+	LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" );
+	return 0;
+	}
 
-extern char *ce_exprtext;
-#define yytext_ptr ce_exprtext
+#define YY_DECL int D4FunctionScanner::yylex()
 
-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[]  );
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
 
 /* Done after the current pattern has been matched and before the
- * corresponding action - sets up ce_exprtext.
+ * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\
 	(yytext_ptr) -= (yy_more_len); \
-	ce_exprleng = (size_t) (yy_cp - (yytext_ptr)); \
+	yyleng = (yy_size_t) (yy_cp - (yytext_ptr)); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
+/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
 	(yy_c_buf_p) = yy_cp;
 
-#define YY_NUM_RULES 32
-#define YY_END_OF_BUFFER 33
+/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
+#define YY_NUM_RULES 29
+#define YY_END_OF_BUFFER 30
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -392,33 +429,33 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[66] =
+static yyconst flex_int16_t yy_accept[64] =
     {   0,
-        0,    0,   28,   28,   33,   31,   26,   31,   27,   31,
-       10,    5,    6,    7,   18,    4,    3,   15,   11,   13,
-        1,    2,    8,    9,   32,   28,   30,   32,   26,   12,
-        0,    0,    0,    0,   10,   16,   17,   14,   28,   29,
-        0,    0,    0,    0,    0,    0,    0,    0,   19,    0,
-        0,    0,    0,    0,   20,   22,    0,    0,    0,    0,
-       21,   23,   24,   25,    0
+        0,    0,   23,   23,   30,   28,   19,   20,   20,   21,
+       22,   28,    4,    5,    1,    7,    6,    3,    2,   23,
+       27,   26,   19,   20,   21,    0,    0,    0,    0,   23,
+       24,   25,    0,    0,    0,    0,    0,    0,    0,    0,
+        8,    0,    0,    0,    0,   10,    0,    0,   12,   14,
+       16,    0,    0,    0,    9,    0,    0,   11,   13,   15,
+       17,   18,    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,    4,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    4,    5,    6,    7,    8,    9,    1,   10,
-       11,   12,    8,   13,    8,    8,    8,    8,   14,   15,
-       16,   17,    8,   18,    8,    8,    8,   19,    1,   20,
-       21,   22,    1,    1,    8,   23,    8,    8,    8,   24,
-        8,    8,   25,    8,    8,    8,    8,    8,    8,    8,
-        8,    8,    8,    8,   26,    8,    8,    8,    8,    8,
-       27,   28,   29,    1,    8,    1,   30,    8,    8,    8,
-
-       31,    8,    8,    8,    8,    8,    8,   32,    8,   33,
-       34,    8,    8,    8,    8,   35,    8,    8,    8,    8,
-       36,    8,   37,    1,   38,   39,    1,    1,    1,    1,
+        1,    2,    5,    6,    5,    7,    5,    1,    1,    8,
+        9,    5,    5,   10,    5,   11,   12,    5,   13,   14,
+       15,   16,    5,   17,    5,   18,    5,   19,   20,    1,
+        1,    1,    1,    5,    5,   21,    5,    5,    5,   22,
+        5,    5,   23,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,   24,    5,    5,    5,    5,    5,
+        1,   25,    1,    1,    5,    1,   26,    5,    5,    5,
+
+       27,    5,    5,    5,    5,    5,    5,   28,    5,   29,
+       30,    5,    5,    5,    5,   31,    5,    5,    5,    5,
+       32,    5,    1,    1,    1,    5,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -435,98 +472,100 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[40] =
+static yyconst flex_int32_t yy_meta[33] =
     {   0,
-        1,    1,    2,    1,    3,    4,    1,    4,    1,    1,
-        1,    1,    1,    4,    4,    4,    4,    4,    1,    1,
-        1,    1,    4,    4,    4,    4,    1,    5,    1,    4,
-        4,    4,    4,    4,    4,    4,    1,    1,    1
+        1,    1,    1,    1,    2,    3,    1,    1,    1,    1,
+        1,    1,    2,    2,    2,    2,    2,    2,    1,    1,
+        2,    2,    2,    2,    4,    2,    2,    2,    2,    2,
+        2,    2
     } ;
 
-static yyconst flex_int16_t yy_base[70] =
+static yyconst flex_int16_t yy_base[67] =
     {   0,
-        0,    0,   35,   36,   94,   95,   40,   72,   95,   21,
-        0,   95,   95,   95,   95,   95,   95,   71,   52,   69,
-       95,   95,   95,   95,   95,    0,   95,    0,   46,   95,
-       53,   56,   54,   61,    0,   95,   95,   95,    0,   95,
-       50,   50,   48,   49,   50,   47,   36,   39,   95,   27,
-       43,   45,   37,   38,   95,   95,   41,   43,   42,   38,
-       95,   95,   95,   95,   95,   64,   66,   71,   75
+        0,    0,   27,   28,   89,   90,   86,   32,   34,    0,
+       90,   18,   90,   90,   90,   90,   90,   90,   90,    0,
+       90,   37,   85,   41,    0,   54,   57,   55,   60,    0,
+       90,   90,   51,   51,   49,   50,   51,   51,   33,   45,
+       90,   44,   57,   59,   56,   90,   41,   32,   90,   90,
+       90,   51,   47,   44,   90,   43,   39,   90,   90,   90,
+       90,   90,   90,   62,   65,   69
     } ;
 
-static yyconst flex_int16_t yy_def[70] =
+static yyconst flex_int16_t yy_def[67] =
     {   0,
-       65,    1,   66,   66,   65,   65,   65,   65,   65,   65,
-       67,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   68,   65,   69,   65,   65,
-       65,   65,   65,   65,   67,   65,   65,   65,   68,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,    0,   65,   65,   65,   65
+       63,    1,   64,   64,   63,   63,   63,   63,   63,   65,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   66,
+       63,   63,   63,   63,   65,   63,   63,   63,   63,   66,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,    0,   63,   63,   63
     } ;
 
-static yyconst flex_int16_t yy_nxt[135] =
+static yyconst flex_int16_t yy_nxt[123] =
     {   0,
-        6,    7,    7,    8,    9,    6,   10,   11,   12,   13,
-       14,   15,   16,   11,   11,   11,   11,   11,   17,   18,
-       19,   20,   11,   11,   11,   11,   21,   11,   22,   11,
-       11,   11,   11,   11,   11,   11,   23,   24,   25,   27,
-       27,   29,   29,   31,   32,   33,   34,   29,   29,   51,
-       57,   52,   58,   59,   64,   60,   63,   62,   61,   56,
-       55,   54,   28,   28,   26,   26,   26,   26,   26,   35,
-       35,   39,   39,   53,   39,   40,   50,   40,   40,   40,
-       49,   48,   47,   46,   45,   44,   43,   42,   41,   38,
-       37,   36,   30,   65,    5,   65,   65,   65,   65,   65,
-
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65
+        6,    7,    8,    9,   10,   11,   12,   13,   14,   15,
+       16,   17,   10,   10,   10,   10,   10,   10,   18,   19,
+       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
+       10,   10,   21,   21,   24,   24,   24,   24,   26,   27,
+       28,   29,   31,   24,   24,   43,   56,   44,   57,   45,
+       46,   22,   22,   52,   62,   53,   61,   54,   55,   60,
+       59,   32,   20,   20,   20,   20,   25,   58,   25,   30,
+       30,   51,   50,   49,   48,   47,   42,   41,   40,   39,
+       38,   37,   36,   35,   34,   33,   23,   23,   63,    5,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63
     } ;
 
-static yyconst flex_int16_t yy_chk[135] =
+static yyconst flex_int16_t yy_chk[123] =
     {   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,    3,
-        4,    7,    7,   10,   10,   10,   10,   29,   29,   47,
-       53,   47,   53,   54,   60,   54,   59,   58,   57,   52,
-       51,   50,    3,    4,   66,   66,   66,   66,   66,   67,
-       67,   68,   68,   48,   68,   69,   46,   69,   69,   69,
-       45,   44,   43,   42,   41,   34,   33,   32,   31,   20,
-       19,   18,    8,    5,   65,   65,   65,   65,   65,   65,
-
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65
+        1,    1,    3,    4,    8,    8,    9,    9,   12,   12,
+       12,   12,   22,   24,   24,   39,   48,   39,   48,   39,
+       39,    3,    4,   47,   57,   47,   56,   47,   47,   54,
+       53,   22,   64,   64,   64,   64,   65,   52,   65,   66,
+       66,   45,   44,   43,   42,   40,   38,   37,   36,   35,
+       34,   33,   29,   28,   27,   26,   23,    7,    5,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63
     } ;
 
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[30] =
+    {   0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1, 0, 0, 1, 0, 0, 0, 0, 0, 0,     };
 
-extern int ce_expr_flex_debug;
-int ce_expr_flex_debug = 0;
+static yyconst flex_int16_t yy_rule_linenum[29] =
+    {   0,
+      121,  122,  123,  125,  126,  128,  129,  131,  132,  133,
+      134,  135,  136,  137,  138,  139,  140,  141,  143,  145,
+      147,  151,  153,  155,  157,  159,  166,  178
+    } ;
 
 /* 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"
+#line 1 "d4_function_scanner.ll"
 /*
  -*- 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.
+ Copyright (c) 2014 OPeNDAP, Inc.
  Author: James Gallagher <jgallagher at opendap.org>
 
  This library is free software; you can redistribute it and/or
@@ -544,76 +583,71 @@ char *ce_exprtext;
  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"
+#line 29 "d4_function_scanner.ll"
 
-#include "config.h"
+//#include "config.h"
 
-static char rcsid[] not_used = {"$Id: ce_expr.lex 27157 2013-09-28 21:22:52Z 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); /* see das.lex */ \
-}
-
-#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);
-
-#define YY_NO_INPUT 1
-
-/* 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
+#include "D4FunctionScanner.h"
+
+/* typedef to make the returns for the tokens shorter */
+
+/* NB: It would be best to use the same scanner (and maybe parser) for
+   both the D4 CE and Function parameters, but for the initial version 
+   far less complexity is require by the Function expression scanner
+   (since the initial version will just support variables, constants, 
+   functions and the $<type> array special form) and not function arguments
+   that are general expressions (like array slicing and/or filters).
+   
+   This comment is here because this is the first place where there is 
+   coupling between the CE parser and its scanner. I'm not sure, however,
+   if one string can be parsed by two parsers if they are using two scanners,
+   so extending the Function parser to allow function args to be any CE 
+   clause may mean some more serious work with the parsers.
+   
+   jhrg 3/10/14 */
+typedef libdap::D4FunctionParser::token token;
+
+/* This was added because of some notes on the net about compiler version
+   issues. I don't know if it's needed when using the C++ mode of flex. */
+#undef yywrap
+#define yywrap() 1
+
+/* define yyterminate as this instead of NULL */
+#define yyterminate() return(token::END)
+
+/* Use this if several scanners are needed. This will cause flex to
+   #define yyFlexLexer to be <prefix>FlexLexer (the yyFlexLexer is defined
+   in lex.<prefix>.cc. jhrg 8/8/13 */
+/* These two options turn on line counting - useful for error messages - 
+   and debugging, respectively. When debugging is on, it's possible to see
+   which scanner rules are used at which points in the input. */
+/* Do not output the default rule (where any unmatched input is echoed to 
+   stdout). When set, nodefault will cause the scanner to exit on an error. */
+/* noyywrap makes the scanner assume that EOF/EOS is the end of the input.
+   If this is not set, the scanner will assume there are more files to 
+   scan. */ 
+/* When set, warn prints a message when the default rule can be matched
+   but nodefault is given (among other warnings). */
+
+/* This pattern is slightly different from the one used by the CE scanner
+   because it allows a WORD to start with a '#' so that the #<type> 
+   array constant syntax can be used in functions. Otherwise, a WORD must
+   be able to contain this hideous mix of characters because a variable 
+   can. jhrg 3/10/14 */
+/* I added these tokens because floating point values may contain dots and
+   added a '.' to WORD will break the parsing of paths (or make for some 
+   fairly obscure code - where $Float32() takes tokens that match 'path'.
+   Since we have a separate scanner for the function expressions, might as
+   well add a FLOAT token... jhg 3/17/14 
+FLOAT   [-+eE.0-9][-+eE.0-9]*
 */
-#line 617 "lex.ce_expr.cc"
+#line 110 "d4_function_scanner.ll"
+// Code run each time a pattern is matched
+#define YY_USER_ACTION loc->columns(yyleng);
+#line 651 "lex.d4_function.cc"
 
 #define INITIAL 0
 #define quote 1
@@ -623,55 +657,31 @@ static void store_op(int op);
  * 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.
  */
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
 #include <unistd.h>
+/* %endif */
 #endif
 
 #ifndef YY_EXTRA_TYPE
 #define YY_EXTRA_TYPE void *
 #endif
 
-static int yy_init_globals (void );
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int ce_exprlex_destroy (void );
-
-int ce_exprget_debug (void );
+/* %if-c-only Reentrant structure and macros (non-C++). */
+/* %if-reentrant */
+/* %if-c-only */
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif End reentrant structures and macros. */
+/* %if-bison-bridge */
+/* %endif */
+/* %not-for-header */
 
-void ce_exprset_debug (int debug_flag  );
+/* %ok-for-header */
 
-YY_EXTRA_TYPE ce_exprget_extra (void );
-
-void ce_exprset_extra (YY_EXTRA_TYPE user_defined  );
-
-FILE *ce_exprget_in (void );
-
-void ce_exprset_in  (FILE * in_str  );
-
-FILE *ce_exprget_out (void );
-
-void ce_exprset_out  (FILE * out_str  );
-
-int ce_exprget_leng (void );
-
-char *ce_exprget_text (void );
-
-int ce_exprget_lineno (void );
-
-void ce_exprset_lineno (int line_number  );
-
-/* 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
+/* %endif */
 
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char *,yyconst char *,int );
@@ -682,15 +692,17 @@ static int yy_flex_strlen (yyconst char * );
 #endif
 
 #ifndef YY_NO_INPUT
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
 
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
+/* %ok-for-header */
 
+/* %endif */
 #endif
 
+/* %if-c-only */
+/* %endif */
+
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
 #define YY_READ_BUF_SIZE 8192
@@ -698,10 +710,11 @@ static int input (void );
 
 /* 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 do { if (fwrite( ce_exprtext, ce_exprleng, 1, ce_exprout )) {} } while (0)
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
+/* %if-c++-only C++ definition */
+#define ECHO LexerOutput( yytext, yyleng )
+/* %endif */
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -709,34 +722,12 @@ static int input (void );
  */
 #ifndef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-		{ \
-		int c = '*'; \
-		unsigned 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); \
-			} \
-		}\
+/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\
 \
+/* %if-c++-only C++ definition \ */\
+	if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+/* %endif */
 
 #endif
 
@@ -755,23 +746,39 @@ static int input (void );
 
 /* Report a fatal error. */
 #ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+#define YY_FATAL_ERROR(msg) LexerError( msg )
+/* %endif */
 #endif
 
+/* %if-tables-serialization structures and prototypes */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* %tables-yydmap generated elements */
+/* %endif */
 /* end tables serialization structures and prototypes */
 
+/* %ok-for-header */
+
 /* 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)
+/* %if-c-only Standard (non-C++) definition */
+/* %endif */
+/* %if-c++-only C++ definition */
+#define YY_DECL int yyFlexLexer::yylex()
+/* %endif */
 #endif /* !YY_DECL */
 
-/* Code executed at the beginning of each rule, after ce_exprtext and ce_exprleng
+/* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
  */
 #ifndef YY_USER_ACTION
@@ -783,9 +790,12 @@ extern int ce_exprlex (void);
 #define YY_BREAK break;
 #endif
 
+/* %% [6.0] YY_RULE_SETUP definition goes here */
 #define YY_RULE_SETUP \
 	YY_USER_ACTION
 
+/* %not-for-header */
+
 /** The main scanner function which does all the work.
  */
 YY_DECL
@@ -794,10 +804,16 @@ YY_DECL
 	register char *yy_cp, *yy_bp;
 	register int yy_act;
     
-#line 132 "ce_expr.lex"
+/* %% [7.0] user's declarations go here */
+#line 114 "d4_function_scanner.ll"
+
+
+
+// Code run each time yylex is called
+loc->step();
 
 
-#line 801 "lex.ce_expr.cc"
+#line 817 "lex.d4_function.cc"
 
 	if ( !(yy_init) )
 		{
@@ -810,23 +826,32 @@ YY_DECL
 		if ( ! (yy_start) )
 			(yy_start) = 1;	/* first start state */
 
-		if ( ! ce_exprin )
-			ce_exprin = stdin;
+		if ( ! yyin )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+			yyin = & std::cin;
+/* %endif */
 
-		if ( ! ce_exprout )
-			ce_exprout = stdout;
+		if ( ! yyout )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+			yyout = & std::cout;
+/* %endif */
 
 		if ( ! YY_CURRENT_BUFFER ) {
-			ce_exprensure_buffer_stack ();
+			yyensure_buffer_stack ();
 			YY_CURRENT_BUFFER_LVALUE =
-				ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+				yy_create_buffer( yyin, YY_BUF_SIZE );
 		}
 
-		ce_expr_load_buffer_state( );
+		yy_load_buffer_state(  );
 		}
 
 	while ( 1 )		/* loops until end-of-file is reached */
 		{
+/* %% [8.0] yymore()-related code goes here */
 		(yy_more_len) = 0;
 		if ( (yy_more_flag) )
 			{
@@ -835,7 +860,7 @@ YY_DECL
 			}
 		yy_cp = (yy_c_buf_p);
 
-		/* Support of ce_exprtext. */
+		/* Support of yytext. */
 		*yy_cp = (yy_hold_char);
 
 		/* yy_bp points to the position in yy_ch_buf of the start of
@@ -843,6 +868,7 @@ YY_DECL
 		 */
 		yy_bp = yy_cp;
 
+/* %% [9.0] code to set up and find next match goes here */
 		yy_current_state = (yy_start);
 yy_match:
 		do
@@ -856,29 +882,55 @@ yy_match:
 			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 >= 66 )
+				if ( yy_current_state >= 64 )
 					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] != 95 );
+		while ( yy_current_state != 63 );
+		yy_cp = (yy_last_accepting_cpos);
+		yy_current_state = (yy_last_accepting_state);
 
 yy_find_action:
+/* %% [10.0] code to find the action number goes here */
 		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;
 
+/* %% [11.0] code for yylineno update goes here */
+
+		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+			{
+			yy_size_t yyl;
+			for ( yyl = (yy_more_len); yyl < yyleng; ++yyl )
+				if ( yytext[yyl] == '\n' )
+					   
+    yylineno++;
+;
+			}
+
 do_action:	/* This label is used only to access EOF actions. */
 
+/* %% [12.0] debug code goes here */
+		if ( yy_flex_debug )
+			{
+			if ( yy_act == 0 )
+				std::cerr << "--scanner backing up\n";
+			else if ( yy_act < 29 )
+				std::cerr << "--accepting rule at line " << yy_rule_linenum[yy_act] <<
+				         "(\"" << yytext << "\")\n";
+			else if ( yy_act == 29 )
+				std::cerr << "--accepting default rule (\"" << yytext << "\")\n";
+			else if ( yy_act == 30 )
+				std::cerr << "--(end of buffer or a NUL)\n";
+			else
+				std::cerr << "--EOF (start condition " << YY_START << ")\n";
+			}
+
 		switch ( yy_act )
 	{ /* beginning of action switch */
+/* %% [13.0] actions go here */
 			case 0: /* must back up */
 			/* undo the effects of YY_DO_BEFORE_ACTION */
 			*yy_cp = (yy_hold_char);
@@ -888,190 +940,178 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 134 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 121 "d4_function_scanner.ll"
+return token::COMMA;
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 135 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 122 "d4_function_scanner.ll"
+return token::SEMICOLON;
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 136 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 123 "d4_function_scanner.ll"
+return token::COLON;
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 137 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 125 "d4_function_scanner.ll"
+return token::LPAREN;
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 138 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 126 "d4_function_scanner.ll"
+return token::RPAREN;
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 139 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 128 "d4_function_scanner.ll"
+return token::GROUP_SEP;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 140 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 129 "d4_function_scanner.ll"
+return token::PATH_SEP;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 141 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 131 "d4_function_scanner.ll"
+return token::DOLLAR_BYTE;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 142 "ce_expr.lex"
-return (int)*ce_exprtext;
+#line 132 "d4_function_scanner.ll"
+return token::DOLLAR_UINT8;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 144 "ce_expr.lex"
-store_id(); return SCAN_WORD;
+#line 133 "d4_function_scanner.ll"
+return token::DOLLAR_INT8;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 146 "ce_expr.lex"
-store_op(SCAN_EQUAL); return SCAN_EQUAL;
+#line 134 "d4_function_scanner.ll"
+return token::DOLLAR_UINT16;
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 147 "ce_expr.lex"
-store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
+#line 135 "d4_function_scanner.ll"
+return token::DOLLAR_INT16;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 148 "ce_expr.lex"
-store_op(SCAN_GREATER); return SCAN_GREATER;
+#line 136 "d4_function_scanner.ll"
+return token::DOLLAR_UINT32;
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 149 "ce_expr.lex"
-store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
+#line 137 "d4_function_scanner.ll"
+return token::DOLLAR_INT32;
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 150 "ce_expr.lex"
-store_op(SCAN_LESS); return SCAN_LESS;
+#line 138 "d4_function_scanner.ll"
+return token::DOLLAR_UINT64;
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 151 "ce_expr.lex"
-store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
+#line 139 "d4_function_scanner.ll"
+return token::DOLLAR_INT64;
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 152 "ce_expr.lex"
-store_op(SCAN_REGEXP); return SCAN_REGEXP;
+#line 140 "d4_function_scanner.ll"
+return token::DOLLAR_FLOAT32;
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 154 "ce_expr.lex"
-store_op(SCAN_STAR); return SCAN_STAR;
+#line 141 "d4_function_scanner.ll"
+return token::DOLLAR_FLOAT64;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 156 "ce_expr.lex"
-return SCAN_HASH_BYTE;
+#line 143 "d4_function_scanner.ll"
+/* ignore these */
 	YY_BREAK
 case 20:
+/* rule 20 can match eol */
 YY_RULE_SETUP
-#line 157 "ce_expr.lex"
-return SCAN_HASH_INT16;
+#line 145 "d4_function_scanner.ll"
+/* ignore these */
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 158 "ce_expr.lex"
-return SCAN_HASH_UINT16;
+#line 147 "d4_function_scanner.ll"
+{ yylval->build<std::string>(yytext); return token::WORD; }
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 149 "d4_function_scanner.ll"
+return token::END;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 159 "ce_expr.lex"
-return SCAN_HASH_INT32;
+#line 151 "d4_function_scanner.ll"
+{ BEGIN(quote); yymore(); }
 	YY_BREAK
 case 23:
+/* rule 23 can match eol */
 YY_RULE_SETUP
-#line 160 "ce_expr.lex"
-return SCAN_HASH_UINT32;
+#line 153 "d4_function_scanner.ll"
+yymore(); /* Anything that's not a double quote or a backslash */
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 161 "ce_expr.lex"
-return SCAN_HASH_FLOAT32;
+#line 155 "d4_function_scanner.ll"
+yymore(); /* This matches the escaped double quote (\") */
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 162 "ce_expr.lex"
-return SCAN_HASH_FLOAT64;
+#line 157 "d4_function_scanner.ll"
+yymore(); /* This matches an escaped escape (\\) */
 	YY_BREAK
 case 26:
-/* rule 26 can match eol */
 YY_RULE_SETUP
-#line 164 "ce_expr.lex"
-
-	YY_BREAK
-case YY_STATE_EOF(INITIAL):
-#line 165 "ce_expr.lex"
-yy_init = 1; yyterminate();
+#line 159 "d4_function_scanner.ll"
+{
+                    BEGIN(INITIAL);
+                    if (yytext) {
+                        YY_FATAL_ERROR("Inside a string, backslash (\\) can escape a double quote or must itself be escaped (\\\\).");
+                    }
+                }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 167 "ce_expr.lex"
-BEGIN(quote); yymore();
-	YY_BREAK
-case 28:
-/* rule 28 can match eol */
-YY_RULE_SETUP
-#line 169 "ce_expr.lex"
-yymore(); /*"*/
-	YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 171 "ce_expr.lex"
-yymore();
-	YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 173 "ce_expr.lex"
+#line 166 "d4_function_scanner.ll"
 { 
-    		  BEGIN(INITIAL); 
-              store_str();
-              return SCAN_STR;
+                /* An unescaped double quote in the 'quote' state indicates the end of the string */
+                BEGIN(INITIAL); 
+                yylval->build<std::string>(yytext); 
+                return token::STRING;
             }
 	YY_BREAK
 case YY_STATE_EOF(quote):
-#line 179 "ce_expr.lex"
+#line 173 "d4_function_scanner.ll"
 {
                   BEGIN(INITIAL);   /* resetting the state is needed for reentrant parsers */
-                  char msg[256];
-                  sprintf(msg, "Unterminated quote\n");
-                  YY_FATAL_ERROR(msg);
+                  YY_FATAL_ERROR("Unterminated quote");
                 }
 	YY_BREAK
-case 31:
-/* rule 31 can match eol */
+case 28:
 YY_RULE_SETUP
-#line 186 "ce_expr.lex"
+#line 178 "d4_function_scanner.ll"
 {
-                  if (ce_exprtext) {	/* suppress msgs about `' chars */
-                    fprintf(stderr, "Character `%c' is not", *ce_exprtext);
-                    fprintf(stderr, " allowed and has been ignored\n");
-                  }
-		        }
+        BEGIN(INITIAL);
+        if (yytext) {
+            YY_FATAL_ERROR("Characters found in the input were not recognized.");
+        }
+    }
 	YY_BREAK
-case 32:
+case 29:
 YY_RULE_SETUP
-#line 192 "ce_expr.lex"
-ECHO;
+#line 184 "d4_function_scanner.ll"
+YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 1075 "lex.ce_expr.cc"
+#line 1115 "lex.d4_function.cc"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1086,15 +1126,15 @@ ECHO;
 			{
 			/* 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
+			 * just pointed yyin at a new source and called
+			 * yylex().  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_input_file = yyin;
 			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
 			}
 
@@ -1136,7 +1176,9 @@ ECHO;
 
 			else
 				{
-				yy_cp = (yy_c_buf_p);
+/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
+				yy_cp = (yy_last_accepting_cpos);
+				yy_current_state = (yy_last_accepting_state);
 				goto yy_find_action;
 				}
 			}
@@ -1147,11 +1189,11 @@ ECHO;
 				{
 				(yy_did_buffer_switch_on_eof) = 0;
 
-				if ( ce_exprwrap( ) )
+				if ( yywrap(  ) )
 					{
 					/* Note: because we've taken care in
 					 * yy_get_next_buffer() to have set up
-					 * ce_exprtext, we can now set up
+					 * yytext, 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
@@ -1200,7 +1242,103 @@ ECHO;
 			"fatal flex scanner internal error--no action found" );
 	} /* end of action switch */
 		} /* end of scanning one token */
-} /* end of ce_exprlex */
+} /* end of yylex */
+/* %ok-for-header */
+
+/* %if-c++-only */
+/* %not-for-header */
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout )
+{
+	yyin = arg_yyin;
+	yyout = arg_yyout;
+	yy_c_buf_p = 0;
+	yy_init = 0;
+	yy_start = 0;
+	yy_flex_debug = 0;
+	yylineno = 1;	// this will only get updated if %option yylineno
+
+	yy_did_buffer_switch_on_eof = 0;
+
+	yy_looking_for_trail_begin = 0;
+	yy_more_flag = 0;
+	yy_more_len = 0;
+	yy_more_offset = yy_prev_more_offset = 0;
+
+	yy_start_stack_ptr = yy_start_stack_depth = 0;
+	yy_start_stack = NULL;
+
+	yy_buffer_stack = 0;
+	yy_buffer_stack_top = 0;
+	yy_buffer_stack_max = 0;
+
+	yy_state_buf = 0;
+
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::~yyFlexLexer()
+{
+	delete [] yy_state_buf;
+	d4_functionfree(yy_start_stack  );
+	yy_delete_buffer( YY_CURRENT_BUFFER );
+	d4_functionfree(yy_buffer_stack  );
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out )
+{
+	if ( new_in )
+		{
+		yy_delete_buffer( YY_CURRENT_BUFFER );
+		yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE  ) );
+		}
+
+	if ( new_out )
+		yyout = new_out;
+}
+
+#ifdef YY_INTERACTIVE
+size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ )
+#else
+size_t yyFlexLexer::LexerInput( char* buf, size_t max_size )
+#endif
+{
+	if ( yyin->eof() || yyin->fail() )
+		return 0;
+
+#ifdef YY_INTERACTIVE
+	yyin->get( buf[0] );
+
+	if ( yyin->eof() )
+		return 0;
+
+	if ( yyin->bad() )
+		return -1;
+
+	return 1;
+
+#else
+	(void) yyin->read( buf, max_size );
+
+	if ( yyin->bad() )
+		return -1;
+	else
+		return yyin->gcount();
+#endif
+}
+
+void yyFlexLexer::LexerOutput( const char* buf, size_t size )
+{
+	(void) yyout->write( buf, size );
+}
+/* %ok-for-header */
+
+/* %endif */
 
 /* yy_get_next_buffer - try to read in a new buffer
  *
@@ -1209,7 +1347,11 @@ ECHO;
  *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  *	EOB_ACT_END_OF_FILE - end of file
  */
-static int yy_get_next_buffer (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+int yyFlexLexer::yy_get_next_buffer()
+/* %endif */
 {
     	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
 	register char *source = (yytext_ptr);
@@ -1255,7 +1397,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1269,7 +1411,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1278,7 +1420,7 @@ static int yy_get_next_buffer (void)
 
 				b->yy_ch_buf = (char *)
 					/* Include room in for 2 EOB chars. */
-					ce_exprrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+					d4_functionrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
 				}
 			else
 				/* Can't grow it, we don't own it. */
@@ -1300,7 +1442,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1310,7 +1452,7 @@ static int yy_get_next_buffer (void)
 		if ( number_to_move == YY_MORE_ADJ )
 			{
 			ret_val = EOB_ACT_END_OF_FILE;
-			ce_exprrestart(ce_exprin  );
+			yyrestart( yyin  );
 			}
 
 		else
@@ -1327,7 +1469,7 @@ static int yy_get_next_buffer (void)
 	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ce_exprrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) d4_functionrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
 	}
@@ -1343,15 +1485,23 @@ static int yy_get_next_buffer (void)
 
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
-    static yy_state_type yy_get_previous_state (void)
+/* %if-c-only */
+/* %not-for-header */
+
+/* %endif */
+/* %if-c++-only */
+    yy_state_type yyFlexLexer::yy_get_previous_state()
+/* %endif */
 {
 	register yy_state_type yy_current_state;
 	register char *yy_cp;
     
+/* %% [15.0] code to get the start state into yy_current_state goes here */
 	yy_current_state = (yy_start);
 
 	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
 		{
+/* %% [16.0] code to find the next state goes here */
 		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
 		if ( yy_accept[yy_current_state] )
 			{
@@ -1361,7 +1511,7 @@ static int yy_get_next_buffer (void)
 		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 >= 66 )
+			if ( yy_current_state >= 64 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1375,10 +1525,15 @@ static int yy_get_next_buffer (void)
  * synopsis
  *	next_state = yy_try_NUL_trans( current_state );
  */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state )
+/* %endif */
 {
 	register int yy_is_jam;
-    	register char *yy_cp = (yy_c_buf_p);
+    /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */
+	register char *yy_cp = (yy_c_buf_p);
 
 	register YY_CHAR yy_c = 1;
 	if ( yy_accept[yy_current_state] )
@@ -1389,22 +1544,69 @@ static int yy_get_next_buffer (void)
 	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 >= 66 )
+		if ( yy_current_state >= 64 )
 			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 == 65);
+	yy_is_jam = (yy_current_state == 63);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
 
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yyunput( int c, register char* yy_bp)
+/* %endif */
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up yytext */
+	*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 yy_size_t 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;
+
+/* %% [18.0] update yylineno here */
+
+    if ( c == '\n' ){
+        --yylineno;
+    }
 
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+/* %if-c-only */
+/* %endif */
+
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    int yyFlexLexer::yyinput()
+/* %endif */
 {
 	int c;
     
@@ -1422,7 +1624,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1439,14 +1641,14 @@ static int yy_get_next_buffer (void)
 					 */
 
 					/* Reset buffer status. */
-					ce_exprrestart(ce_exprin );
+					yyrestart( yyin );
 
 					/*FALLTHROUGH*/
 
 				case EOB_ACT_END_OF_FILE:
 					{
-					if ( ce_exprwrap( ) )
-						return EOF;
+					if ( yywrap(  ) )
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1465,44 +1667,59 @@ static int yy_get_next_buffer (void)
 		}
 
 	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve ce_exprtext */
+	*(yy_c_buf_p) = '\0';	/* preserve yytext */
 	(yy_hold_char) = *++(yy_c_buf_p);
 
+/* %% [19.0] update BOL and yylineno */
+	if ( c == '\n' )
+		   
+    yylineno++;
+;
+
 	return c;
 }
-#endif	/* ifndef YY_NO_INPUT */
+/* %if-c-only */
+/* %endif */
 
 /** 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-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yyrestart( std::istream* input_file )
+/* %endif */
 {
     
 	if ( ! YY_CURRENT_BUFFER ){
-        ce_exprensure_buffer_stack ();
+        yyensure_buffer_stack ();
 		YY_CURRENT_BUFFER_LVALUE =
-            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+            yy_create_buffer( yyin, YY_BUF_SIZE );
 	}
 
-	ce_expr_init_buffer(YY_CURRENT_BUFFER,input_file );
-	ce_expr_load_buffer_state( );
+	yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+	yy_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 )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+/* %endif */
 {
     
 	/* TODO. We should be able to replace this entire function body
 	 * with
-	 *		ce_exprpop_buffer_state();
-	 *		ce_exprpush_buffer_state(new_buffer);
+	 *		yypop_buffer_state();
+	 *		yypush_buffer_state(new_buffer);
      */
-	ce_exprensure_buffer_stack ();
+	yyensure_buffer_stack ();
 	if ( YY_CURRENT_BUFFER == new_buffer )
 		return;
 
@@ -1515,21 +1732,25 @@ static int yy_get_next_buffer (void)
 		}
 
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	ce_expr_load_buffer_state( );
+	yy_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
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() 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)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_load_buffer_state()
+/* %endif */
 {
     	(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;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
 	(yy_hold_char) = *(yy_c_buf_p);
 }
 
@@ -1539,35 +1760,43 @@ static void ce_expr_load_buffer_state  (void)
  * 
  * @return the allocated buffer state.
  */
-    YY_BUFFER_STATE ce_expr_create_buffer  (FILE * file, int  size )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size )
+/* %endif */
 {
 	YY_BUFFER_STATE b;
     
-	b = (YY_BUFFER_STATE) ce_expralloc(sizeof( struct yy_buffer_state )  );
+	b = (YY_BUFFER_STATE) d4_functionalloc(sizeof( struct yy_buffer_state )  );
 	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_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  );
+	b->yy_ch_buf = (char *) d4_functionalloc(b->yy_buf_size + 2  );
 	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
 	b->yy_is_our_buffer = 1;
 
-	ce_expr_init_buffer(b,file );
+	yy_init_buffer( b, file );
 
 	return b;
 }
 
 /** Destroy the buffer.
- * @param b a buffer created with ce_expr_create_buffer()
+ * @param b a buffer created with yy_create_buffer()
  * 
  */
-    void ce_expr_delete_buffer (YY_BUFFER_STATE  b )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b )
+/* %endif */
 {
     
 	if ( ! b )
@@ -1577,31 +1806,40 @@ static void ce_expr_load_buffer_state  (void)
 		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
 
 	if ( b->yy_is_our_buffer )
-		ce_exprfree((void *) b->yy_ch_buf  );
+		d4_functionfree((void *) b->yy_ch_buf  );
 
-	ce_exprfree((void *) b  );
+	d4_functionfree((void *) b  );
 }
 
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
+/* %if-c-only */
+/* %endif */
+
+/* %if-c++-only */
+
+extern "C" int isatty (int );
+
+/* %endif */
+
 /* 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.
+ * such as during a yyrestart() or at EOF.
  */
-    static void ce_expr_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file )
+/* %endif */
 
 {
 	int oerrno = errno;
     
-	ce_expr_flush_buffer(b );
+	yy_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.
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
      * In that case, we don't want to reset the lineno or column.
      */
     if (b != YY_CURRENT_BUFFER){
@@ -1609,8 +1847,11 @@ extern int isatty (int );
         b->yy_bs_column = 0;
     }
 
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+	b->yy_is_interactive = 0;
+/* %endif */
 	errno = oerrno;
 }
 
@@ -1618,7 +1859,11 @@ extern int isatty (int );
  * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
  * 
  */
-    void ce_expr_flush_buffer (YY_BUFFER_STATE  b )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b )
+/* %endif */
 {
     	if ( ! b )
 		return;
@@ -1638,23 +1883,28 @@ extern int isatty (int );
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
 	if ( b == YY_CURRENT_BUFFER )
-		ce_expr_load_buffer_state( );
+		yy_load_buffer_state(  );
 }
 
+/* %if-c-or-c++ */
 /** 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-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer)
+/* %endif */
 {
     	if (new_buffer == NULL)
 		return;
 
-	ce_exprensure_buffer_stack();
+	yyensure_buffer_stack();
 
-	/* This block is copied from ce_expr_switch_to_buffer. */
+	/* This block is copied from yy_switch_to_buffer. */
 	if ( YY_CURRENT_BUFFER )
 		{
 		/* Flush out information for old buffer. */
@@ -1668,37 +1918,49 @@ void ce_exprpush_buffer_state (YY_BUFFER_STATE new_buffer )
 		(yy_buffer_stack_top)++;
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
 
-	/* copied from ce_expr_switch_to_buffer. */
-	ce_expr_load_buffer_state( );
+	/* copied from yy_switch_to_buffer. */
+	yy_load_buffer_state(  );
 	(yy_did_buffer_switch_on_eof) = 1;
 }
+/* %endif */
 
+/* %if-c-or-c++ */
 /** Removes and deletes the top of the stack, if present.
  *  The next element becomes the new top.
  *  
  */
-void ce_exprpop_buffer_state (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yypop_buffer_state (void)
+/* %endif */
 {
     	if (!YY_CURRENT_BUFFER)
 		return;
 
-	ce_expr_delete_buffer(YY_CURRENT_BUFFER );
+	yy_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_load_buffer_state(  );
 		(yy_did_buffer_switch_on_eof) = 1;
 	}
 }
+/* %endif */
 
+/* %if-c-or-c++ */
 /* Allocates the stack if it does not exist.
  *  Guarantees space for at least one push.
  */
-static void ce_exprensure_buffer_stack (void)
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::yyensure_buffer_stack(void)
+/* %endif */
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1707,11 +1969,11 @@ static void ce_exprensure_buffer_stack (void)
 		 * immediate realloc on the next call.
          */
 		num_to_alloc = 1;
-		(yy_buffer_stack) = (struct yy_buffer_state**)ce_expralloc
+		(yy_buffer_stack) = (struct yy_buffer_state**)d4_functionalloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ce_exprensure_buffer_stack()" );
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 								  
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 				
@@ -1726,114 +1988,91 @@ static void ce_exprensure_buffer_stack (void)
 		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) = (struct yy_buffer_state**)d4_functionrealloc
 								((yy_buffer_stack),
 								num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ce_exprensure_buffer_stack()" );
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 
 		/* 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;
 	}
 }
+/* %endif */
 
-/** 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;
+/* %if-c-only */
+/* %endif */
 
-	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()" );
+/* %if-c-only */
+/* %endif */
 
-	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;
+/* %if-c-only */
+/* %endif */
 
-	ce_expr_switch_to_buffer(b  );
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_push_state( int new_state )
+/* %endif */
+{
+    	if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) )
+		{
+		yy_size_t new_size;
 
-	return b;
-}
+		(yy_start_stack_depth) += YY_START_STACK_INCR;
+		new_size = (yy_start_stack_depth) * sizeof( int );
 
-/** 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 yystr 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) );
-}
+		if ( ! (yy_start_stack) )
+			(yy_start_stack) = (int *) d4_functionalloc(new_size  );
 
-/** 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()" );
+		else
+			(yy_start_stack) = (int *) d4_functionrealloc((void *) (yy_start_stack),new_size  );
 
-	for ( i = 0; i < _yybytes_len; ++i )
-		buf[i] = yybytes[i];
+		if ( ! (yy_start_stack) )
+			YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+		}
 
-	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+	(yy_start_stack)[(yy_start_stack_ptr)++] = YY_START;
 
-	b = ce_expr_scan_buffer(buf,n );
-	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in ce_expr_scan_bytes()" );
+	BEGIN(new_state);
+}
 
-	/* It's okay to grow etc. this buffer, and we should throw it
-	 * away when we're done.
-	 */
-	b->yy_is_our_buffer = 1;
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    void yyFlexLexer::yy_pop_state()
+/* %endif */
+{
+    	if ( --(yy_start_stack_ptr) < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
 
-	return b;
+	BEGIN((yy_start_stack)[(yy_start_stack_ptr)]);
+}
+
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+    int yyFlexLexer::yy_top_state()
+/* %endif */
+{
+    	return (yy_start_stack)[(yy_start_stack_ptr) - 1];
 }
 
 #ifndef YY_EXIT_FAILURE
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yy_fatal_error (yyconst char* msg )
+/* %if-c-only */
+/* %endif */
+/* %if-c++-only */
+void yyFlexLexer::LexerError( yyconst char msg[] )
 {
-    	(void) fprintf( stderr, "%s\n", msg );
+    	std::cerr << msg << std::endl;
 	exit( YY_EXIT_FAILURE );
 }
+/* %endif */
 
 /* Redefine yyless() so it works in section 3 code. */
 
@@ -1841,146 +2080,38 @@ static void yy_fatal_error (yyconst char* msg )
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ce_exprtext. */ \
+		/* Undo effects of setting up yytext. */ \
         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; \
+		yytext[yyleng] = (yy_hold_char); \
+		(yy_c_buf_p) = yytext + yyless_macro_arg; \
 		(yy_hold_char) = *(yy_c_buf_p); \
 		*(yy_c_buf_p) = '\0'; \
-		ce_exprleng = yyless_macro_arg; \
+		yyleng = 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;
-}
+/* %if-c-only */
+/* %if-reentrant */
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif */
 
-/** 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;
-}
+/* %if-reentrant */
+/* %if-bison-bridge */
+/* %endif */
+/* %endif if-c-only */
 
-/** 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 ;
-}
+/* %if-c-only */
+/* %endif */
 
-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;
-}
+/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
+/* %if-reentrant */
+/* %endif */
+/* %endif */
 
 /*
  * Internal utility routines.
@@ -2006,12 +2137,12 @@ static int yy_flex_strlen (yyconst char * s )
 }
 #endif
 
-void *ce_expralloc (yy_size_t  size )
+void *d4_functionalloc (yy_size_t  size )
 {
 	return (void *) malloc( size );
 }
 
-void *ce_exprrealloc  (void * ptr, yy_size_t  size )
+void *d4_functionrealloc  (void * ptr, yy_size_t  size )
 {
 	/* The cast to (char *) in the following accommodates both
 	 * implementations that use char* generic pointers, and those
@@ -2023,69 +2154,19 @@ void *ce_exprrealloc  (void * ptr, yy_size_t  size )
 	return (void *) realloc( (char *) ptr, size );
 }
 
-void ce_exprfree (void * ptr )
+void d4_functionfree (void * ptr )
 {
-	free( (char *) ptr );	/* see ce_exprrealloc() for (char *) cast */
+	free( (char *) ptr );	/* see d4_functionrealloc() for (char *) cast */
 }
 
+/* %if-tables-serialization definitions */
+/* %define-yytables   The name for this specific scanner's tables. */
 #define YYTABLES_NAME "yytables"
+/* %endif */
 
-#line 192 "ce_expr.lex"
+/* %ok-for-header */
 
+#line 184 "d4_function_scanner.ll"
 
 
-// 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, ce_exprtext, 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(ce_exprtext); // move all calls of www2id into the parser. jhrg 7/5/13 www2id(string(ce_exprtext)));
-
-    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/d4_ce/location.hh b/d4_ce/location.hh
new file mode 100644
index 0000000..b07689e
--- /dev/null
+++ b/d4_ce/location.hh
@@ -0,0 +1,187 @@
+// A Bison parser, made by GNU Bison 3.0.1.
+
+// Locations for Bison parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file location.hh
+ ** Define the libdap::location class.
+ */
+
+#ifndef YY_YY_LOCATION_HH_INCLUDED
+# define YY_YY_LOCATION_HH_INCLUDED
+
+# include "position.hh"
+
+#line 35 "d4_ce_parser.yy" // location.cc:291
+namespace libdap {
+#line 46 "location.hh" // location.cc:291
+  /// Abstract a location.
+  class location
+  {
+  public:
+
+    /// Construct a location from \a b to \a e.
+    location (const position& b, const position& e)
+      : begin (b)
+      , end (e)
+    {
+    }
+
+    /// Construct a 0-width location in \a p.
+    explicit location (const position& p = position ())
+      : begin (p)
+      , end (p)
+    {
+    }
+
+    /// Construct a 0-width location in \a f, \a l, \a c.
+    explicit location (std::string* f,
+                       unsigned int l = 1u,
+                       unsigned int c = 1u)
+      : begin (f, l, c)
+      , end (f, l, c)
+    {
+    }
+
+
+    /// Initialization.
+    void initialize (std::string* f = YY_NULLPTR,
+                     unsigned int l = 1u,
+                     unsigned int c = 1u)
+    {
+      begin.initialize (f, l, c);
+      end = begin;
+    }
+
+    /** \name Line and Column related manipulators
+     ** \{ */
+  public:
+    /// Reset initial location to final location.
+    void step ()
+    {
+      begin = end;
+    }
+
+    /// Extend the current location to the COUNT next columns.
+    void columns (int count = 1)
+    {
+      end += count;
+    }
+
+    /// Extend the current location to the COUNT next lines.
+    void lines (int count = 1)
+    {
+      end.lines (count);
+    }
+    /** \} */
+
+
+  public:
+    /// Beginning of the located region.
+    position begin;
+    /// End of the located region.
+    position end;
+  };
+
+  /// Join two location objects to create a location.
+  inline location operator+ (location res, const location& end)
+  {
+    res.end = end.end;
+    return res;
+  }
+
+  /// Change end position in place.
+  inline location& operator+= (location& res, int width)
+  {
+    res.columns (width);
+    return res;
+  }
+
+  /// Change end position.
+  inline location operator+ (location res, int width)
+  {
+    return res += width;
+  }
+
+  /// Change end position in place.
+  inline location& operator-= (location& res, int width)
+  {
+    return res += -width;
+  }
+
+  /// Change end position.
+  inline location operator- (const location& begin, int width)
+  {
+    return begin + -width;
+  }
+
+  /// Compare two location objects.
+  inline bool
+  operator== (const location& loc1, const location& loc2)
+  {
+    return loc1.begin == loc2.begin && loc1.end == loc2.end;
+  }
+
+  /// Compare two location objects.
+  inline bool
+  operator!= (const location& loc1, const location& loc2)
+  {
+    return !(loc1 == loc2);
+  }
+
+  /** \brief Intercept output stream redirection.
+   ** \param ostr the destination output stream
+   ** \param loc a reference to the location to redirect
+   **
+   ** Avoid duplicate information.
+   */
+  template <typename YYChar>
+  inline std::basic_ostream<YYChar>&
+  operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
+  {
+    unsigned int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
+    ostr << loc.begin// << "(" << loc.end << ") "
+;
+    if (loc.end.filename
+        && (!loc.begin.filename
+            || *loc.begin.filename != *loc.end.filename))
+      ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
+    else if (loc.begin.line < loc.end.line)
+      ostr << '-' << loc.end.line << '.' << end_col;
+    else if (loc.begin.column < end_col)
+      ostr << '-' << end_col;
+    return ostr;
+  }
+
+#line 35 "d4_ce_parser.yy" // location.cc:291
+} // libdap
+#line 187 "location.hh" // location.cc:291
+#endif // !YY_YY_LOCATION_HH_INCLUDED
diff --git a/d4_ce/position.hh b/d4_ce/position.hh
new file mode 100644
index 0000000..4fe82ae
--- /dev/null
+++ b/d4_ce/position.hh
@@ -0,0 +1,180 @@
+// A Bison parser, made by GNU Bison 3.0.1.
+
+// Positions for Bison parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file position.hh
+ ** Define the libdap::position class.
+ */
+
+#ifndef YY_YY_POSITION_HH_INCLUDED
+# define YY_YY_POSITION_HH_INCLUDED
+
+# include <algorithm> // std::max
+# include <iostream>
+# include <string>
+
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
+
+#line 35 "d4_ce_parser.yy" // location.cc:291
+namespace libdap {
+#line 56 "position.hh" // location.cc:291
+  /// Abstract a position.
+  class position
+  {
+  public:
+    /// Construct a position.
+    explicit position (std::string* f = YY_NULLPTR,
+                       unsigned int l = 1u,
+                       unsigned int c = 1u)
+      : filename (f)
+      , line (l)
+      , column (c)
+    {
+    }
+
+
+    /// Initialization.
+    void initialize (std::string* fn = YY_NULLPTR,
+                     unsigned int l = 1u,
+                     unsigned int c = 1u)
+    {
+      filename = fn;
+      line = l;
+      column = c;
+    }
+
+    /** \name Line and Column related manipulators
+     ** \{ */
+    /// (line related) Advance to the COUNT next lines.
+    void lines (int count = 1)
+    {
+      if (count)
+        {
+          column = 1u;
+          line = add_ (line, count, 1);
+        }
+    }
+
+    /// (column related) Advance to the COUNT next columns.
+    void columns (int count = 1)
+    {
+      column = add_ (column, count, 1);
+    }
+    /** \} */
+
+    /// File name to which this position refers.
+    std::string* filename;
+    /// Current line number.
+    unsigned int line;
+    /// Current column number.
+    unsigned int column;
+
+  private:
+    /// Compute max(min, lhs+rhs) (provided min <= lhs).
+    static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min)
+    {
+      return (0 < rhs || -static_cast<unsigned int>(rhs) < lhs
+              ? rhs + lhs
+              : min);
+    }
+  };
+
+  /// Add and assign a position.
+  inline position&
+  operator+= (position& res, int width)
+  {
+    res.columns (width);
+    return res;
+  }
+
+  /// Add two position objects.
+  inline position
+  operator+ (position res, int width)
+  {
+    return res += width;
+  }
+
+  /// Add and assign a position.
+  inline position&
+  operator-= (position& res, int width)
+  {
+    return res += -width;
+  }
+
+  /// Add two position objects.
+  inline position
+  operator- (position res, int width)
+  {
+    return res -= width;
+  }
+
+  /// Compare two position objects.
+  inline bool
+  operator== (const position& pos1, const position& pos2)
+  {
+    return (pos1.line == pos2.line
+            && pos1.column == pos2.column
+            && (pos1.filename == pos2.filename
+                || (pos1.filename && pos2.filename
+                    && *pos1.filename == *pos2.filename)));
+  }
+
+  /// Compare two position objects.
+  inline bool
+  operator!= (const position& pos1, const position& pos2)
+  {
+    return !(pos1 == pos2);
+  }
+
+  /** \brief Intercept output stream redirection.
+   ** \param ostr the destination output stream
+   ** \param pos a reference to the position to redirect
+   */
+  template <typename YYChar>
+  inline std::basic_ostream<YYChar>&
+  operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
+  {
+    if (pos.filename)
+      ostr << *pos.filename << ':';
+    return ostr << pos.line << '.' << pos.column;
+  }
+
+#line 35 "d4_ce_parser.yy" // location.cc:291
+} // libdap
+#line 180 "position.hh" // location.cc:291
+#endif // !YY_YY_POSITION_HH_INCLUDED
diff --git a/d4_ce/stack.hh b/d4_ce/stack.hh
new file mode 100644
index 0000000..9831fcf
--- /dev/null
+++ b/d4_ce/stack.hh
@@ -0,0 +1,158 @@
+// A Bison parser, made by GNU Bison 3.0.1.
+
+// Stack handling for Bison parsers in C++
+
+// Copyright (C) 2002-2013 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 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, 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.
+
+/**
+ ** \file stack.hh
+ ** Define the libdap::stack class.
+ */
+
+#ifndef YY_YY_STACK_HH_INCLUDED
+# define YY_YY_STACK_HH_INCLUDED
+
+# include <vector>
+
+#line 35 "d4_ce_parser.yy" // stack.hh:133
+namespace libdap {
+#line 46 "stack.hh" // stack.hh:133
+  template <class T, class S = std::vector<T> >
+  class stack
+  {
+  public:
+    // Hide our reversed order.
+    typedef typename S::reverse_iterator iterator;
+    typedef typename S::const_reverse_iterator const_iterator;
+
+    stack ()
+      : seq_ ()
+    {
+    }
+
+    stack (unsigned int n)
+      : seq_ (n)
+    {
+    }
+
+    inline
+    T&
+    operator[] (unsigned int i)
+    {
+      return seq_[seq_.size () - 1 - i];
+    }
+
+    inline
+    const T&
+    operator[] (unsigned int i) const
+    {
+      return seq_[seq_.size () - 1 - i];
+    }
+
+    /// Steal the contents of \a t.
+    ///
+    /// Close to move-semantics.
+    inline
+    void
+    push (T& t)
+    {
+      seq_.push_back (T());
+      operator[](0).move (t);
+    }
+
+    inline
+    void
+    pop (unsigned int n = 1)
+    {
+      for (; n; --n)
+        seq_.pop_back ();
+    }
+
+    void
+    clear ()
+    {
+      seq_.clear ();
+    }
+
+    inline
+    typename S::size_type
+    size () const
+    {
+      return seq_.size ();
+    }
+
+    inline
+    const_iterator
+    begin () const
+    {
+      return seq_.rbegin ();
+    }
+
+    inline
+    const_iterator
+    end () const
+    {
+      return seq_.rend ();
+    }
+
+  private:
+    stack (const stack&);
+    stack& operator= (const stack&);
+    /// The wrapped container.
+    S seq_;
+  };
+
+  /// Present a slice of the top of a stack.
+  template <class T, class S = stack<T> >
+  class slice
+  {
+  public:
+    slice (const S& stack, unsigned int range)
+      : stack_ (stack)
+      , range_ (range)
+    {
+    }
+
+    inline
+    const T&
+    operator [] (unsigned int i) const
+    {
+      return stack_[range_ - i];
+    }
+
+  private:
+    const S& stack_;
+    unsigned int range_;
+  };
+
+#line 35 "d4_ce_parser.yy" // stack.hh:133
+} // libdap
+#line 157 "stack.hh" // stack.hh:133
+
+#endif // !YY_YY_STACK_HH_INCLUDED
diff --git a/das.lex b/das.lex
index f105c54..eab5e11 100644
--- a/das.lex
+++ b/das.lex
@@ -64,7 +64,7 @@
 
 #include <cstdio>
 
-static char rcsid[] not_used ={"$Id: das.lex 27157 2013-09-28 21:22:52Z jimg $"};
+static char rcsid[] not_used ={"$Id$"};
 
 #ifndef _MSC_VER
 #include <string.h>
diff --git a/das.tab.cc b/das.tab.cc
index e3503c8..817a800 100644
--- a/das.tab.cc
+++ b/das.tab.cc
@@ -1,21 +1,19 @@
+/* A Bison parser, made by GNU Bison 3.0.1.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* Bison implementation for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
 
-/* 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 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 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/>.  */
 
@@ -28,7 +26,7 @@
    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.  */
 
@@ -46,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "3.0.1"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -60,29 +58,28 @@
 /* Pull parsers.  */
 #define YYPULL 1
 
-/* 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
 
+#define yylval          daslval
+#define yychar          daschar
 
 /* Copy the first part of user declarations.  */
 
+#line 75 "das.tab.cc" /* yacc.c:339  */
 
-/* Line 189 of yacc.c  */
-#line 81 "das.tab.cc"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -92,15 +89,19 @@
 # define YYERROR_VERBOSE 0
 #endif
 
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+   by #include "das.tab.hh".  */
+#ifndef YY_DAS_DAS_TAB_HH_INCLUDED
+# define YY_DAS_DAS_TAB_HH_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int dasdebug;
 #endif
-
 /* "%code requires" blocks.  */
-
-/* Line 209 of yacc.c  */
-#line 40 "das.yy"
+#line 40 "das.yy" /* yacc.c:355  */
 
 
 #define YYSTYPE char *
@@ -119,7 +120,7 @@
 #include "debug.h"
 #include "parser.h"
 #include "util.h"
-  // #include "das.tab.hh"
+// #include "das.tab.hh"
 
 #ifdef TRACE_NEW
 #include "trace_new.h"
@@ -145,52 +146,48 @@ using namespace libdap ;
 extern int das_line_num;	/* defined in das.lex */
 
 
+#line 150 "das.tab.cc" /* yacc.c:355  */
 
-
-/* Line 209 of yacc.c  */
-#line 152 "das.tab.cc"
-
-/* Tokens.  */
+/* Token type.  */
 #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
-   };
+  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
 
-
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef int YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
 
-/* Copy the second part of user declarations.  */
+extern YYSTYPE daslval;
 
+int dasparse (parser_arg *arg);
 
-/* Line 264 of yacc.c  */
-#line 190 "das.tab.cc"
-/* Unqualified %code blocks.  */
+#endif /* !YY_DAS_DAS_TAB_HH_INCLUDED  */
 
-/* Line 265 of yacc.c  */
-#line 85 "das.yy"
+/* Copy the second part of user declarations.  */
+
+#line 189 "das.tab.cc" /* yacc.c:358  */
+/* Unqualified %code blocks.  */
+#line 85 "das.yy" /* yacc.c:359  */
 
 // No global static objects. We go through this every so often, I guess I
 // should learn... 1/24/2000 jhrg
@@ -230,10 +227,7 @@ static void add_bad_attribute(AttrTable *attr, const string &type,
 			      const string &msg);
 
 
-
-
-/* Line 265 of yacc.c  */
-#line 237 "das.tab.cc"
+#line 231 "das.tab.cc" /* yacc.c:359  */
 
 #ifdef short
 # undef short
@@ -247,11 +241,8 @@ typedef unsigned char yytype_uint8;
 
 #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;
+typedef signed char yytype_int8;
 #endif
 
 #ifdef YYTYPE_UINT16
@@ -271,8 +262,7 @@ typedef short int yytype_int16;
 #  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)
+# elif ! defined YYSIZE_T
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
@@ -283,42 +273,71 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(msgid) msgid
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
 #else
-# define YYUSE(e) /* empty */
+# 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 yyi)
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
 #else
-static int
-YYID (yyi)
-    int yyi;
+# define YY_INITIAL_VALUE(Value) Value
 #endif
-{
-  return yyi;
-}
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
 #endif
 
+
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */
@@ -336,11 +355,11 @@ YYID (yyi)
 #    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)
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -348,8 +367,8 @@ YYID (yyi)
 # endif
 
 # ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+   /* Pacify GCC's 'empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (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
@@ -363,25 +382,23 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
-	     && (defined YYFREE || defined free)))
+             && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
+#   if ! defined malloc && ! defined EXIT_SUCCESS
 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)
+#   if ! defined free && ! defined EXIT_SUCCESS
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
@@ -391,7 +408,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
-	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
@@ -409,42 +426,46 @@ union yyalloc
      ((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
+# define YYCOPY_NEEDED 1
 
 /* 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_alloc, Stack)				\
-    do									\
-      {									\
-	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
-	Stack = &yyptr->Stack_alloc;					\
-	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-	yyptr += yynewbytes / sizeof (*yyptr);				\
-      }									\
-    while (YYID (0))
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
+    do                                                                  \
+      {                                                                 \
+        YYSIZE_T yynewbytes;                                            \
+        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+        Stack = &yyptr->Stack_alloc;                                    \
+        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                 \
+    while (0)
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (0)
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
@@ -456,17 +477,19 @@ union yyalloc
 #define YYNNTS  47
 /* YYNRULES -- Number of rules.  */
 #define YYNRULES  84
-/* YYNRULES -- Number of states.  */
+/* YYNSTATES -- Number of states.  */
 #define YYNSTATES  134
 
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   270
 
-#define YYTRANSLATE(YYX)						\
+#define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, without out-of-bounds checking.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -500,50 +523,7 @@ static const yytype_uint8 yytranslate[] =
 };
 
 #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.  */
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
        0,   194,   194,   194,   211,   212,   216,   217,   223,   224,
@@ -558,7 +538,7 @@ static const yytype_uint16 yyrline[] =
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
@@ -572,13 +552,13 @@ static const char *const yytname[] =
   "$@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
+  "name", "alias", "$@25", "$@26", YY_NULLPTR
 };
 #endif
 
 # ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+   (internal) symbol number NUM (which must be that of a token).  */
 static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
@@ -586,68 +566,18 @@ static const yytype_uint16 yytoknum[] =
 };
 # 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
-};
+#define YYPACT_NINF -76
 
-/* 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
-};
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-76)))
 
-/* 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
-};
+#define YYTABLE_NINF -44
 
-/* 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
-};
+#define yytable_value_is_error(Yytable_value) \
+  0
 
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -76
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
 static const yytype_int8 yypact[] =
 {
      -76,    19,    35,   -76,   -76,    25,    34,   -76,     1,   -76,
@@ -666,7 +596,28 @@ static const yytype_int8 yypact[] =
      -76,   -76,   -76,   -76
 };
 
-/* YYPGOTO[NTERM-NUM].  */
+  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+     Performed when YYTABLE does not 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
+};
+
+  /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
      -76,   -76,   -76,   -76,   111,    73,   -22,   -76,   -76,   -76,
@@ -676,11 +627,19 @@ static const yytype_int8 yypgoto[] =
       -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
+  /* 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
+};
+
+  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule whose
+     number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
       95,    40,    10,   106,   107,    11,    12,    13,    14,    15,
@@ -713,8 +672,8 @@ static const yytype_uint8 yycheck[] =
       18,     4,     4,     4,     4,    42,   123,     6,   121
 };
 
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
+  /* 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,
@@ -733,95 +692,69 @@ static const yytype_uint8 yystos[] =
       62,    62,    61,    60
 };
 
-#define yyerrok		(yyerrstatus = 0)
-#define yyclearin	(yychar = YYEMPTY)
-#define YYEMPTY		(-2)
-#define YYEOF		0
+  /* 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 on the 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
+};
 
-#define YYACCEPT	goto yyacceptlab
-#define YYABORT		goto yyabortlab
-#define YYERROR		goto yyerrorlab
 
+#define yyerrok         (yyerrstatus = 0)
+#define yyclearin       (yychar = YYEMPTY)
+#define YYEMPTY         (-2)
+#define YYEOF           0
 
-/* 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 YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
 
-#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								\
-    {								\
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
       yyerror (arg, 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
+      YYERROR;                                                  \
+    }                                                           \
+while (0)
 
+/* Error token number */
+#define YYTERROR        1
+#define YYERRCODE       256
 
-/* 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
@@ -831,56 +764,47 @@ while (YYID (0))
 #  define YYFPRINTF fprintf
 # endif
 
-# define YYDPRINTF(Args)			\
-do {						\
-  if (yydebug)					\
-    YYFPRINTF Args;				\
-} while (YYID (0))
+# define YYDPRINTF(Args)                        \
+do {                                            \
+  if (yydebug)                                  \
+    YYFPRINTF Args;                             \
+} while (0)
 
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
-do {									  \
-  if (yydebug)								  \
-    {									  \
-      YYFPRINTF (stderr, "%s ", Title);					  \
-      yy_symbol_print (stderr,						  \
-		  Type, Value, arg); \
-      YYFPRINTF (stderr, "\n");						  \
-    }									  \
-} while (YYID (0))
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
+do {                                                                      \
+  if (yydebug)                                                            \
+    {                                                                     \
+      YYFPRINTF (stderr, "%s ", Title);                                   \
+      yy_symbol_print (stderr,                                            \
+                  Type, Value, arg); \
+      YYFPRINTF (stderr, "\n");                                           \
+    }                                                                     \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value 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, parser_arg *arg)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    parser_arg *arg;
-#endif
 {
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
+  YYUSE (arg);
   if (!yyvaluep)
     return;
-  YYUSE (arg);
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
-  YYUSE (yyoutput);
 # endif
-  switch (yytype)
-    {
-      default:
-	break;
-    }
+  YYUSE (yytype);
 }
 
 
@@ -888,23 +812,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg)
 | 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, parser_arg *arg)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, arg)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    parser_arg *arg;
-#endif
 {
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-  else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+  YYFPRINTF (yyoutput, "%s %s (",
+             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
   yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg);
   YYFPRINTF (yyoutput, ")");
@@ -915,16 +827,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, arg)
 | TOP (included).                                                   |
 `------------------------------------------------------------------*/
 
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
-#endif
 {
   YYFPRINTF (stderr, "Stack now");
   for (; yybottom <= yytop; yybottom++)
@@ -935,50 +839,42 @@ yy_stack_print (yybottom, yytop)
   YYFPRINTF (stderr, "\n");
 }
 
-# define YY_STACK_PRINT(Bottom, Top)				\
-do {								\
-  if (yydebug)							\
-    yy_stack_print ((Bottom), (Top));				\
-} while (YYID (0))
+# define YY_STACK_PRINT(Bottom, Top)                            \
+do {                                                            \
+  if (yydebug)                                                  \
+    yy_stack_print ((Bottom), (Top));                           \
+} while (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, parser_arg *arg)
-#else
 static void
-yy_reduce_print (yyvsp, yyrule, arg)
-    YYSTYPE *yyvsp;
-    int yyrule;
-    parser_arg *arg;
-#endif
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, parser_arg *arg)
 {
+  unsigned long int yylno = yyrline[yyrule];
   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);
+             yyrule - 1, yylno);
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
-		       &(yyvsp[(yyi + 1) - (yynrhs)])
-		       		       , arg);
+      yy_symbol_print (stderr,
+                       yystos[yyssp[yyi + 1 - yynrhs]],
+                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                                              , arg);
       YYFPRINTF (stderr, "\n");
     }
 }
 
-# define YY_REDUCE_PRINT(Rule)		\
-do {					\
-  if (yydebug)				\
-    yy_reduce_print (yyvsp, Rule, arg); \
-} while (YYID (0))
+# define YY_REDUCE_PRINT(Rule)          \
+do {                                    \
+  if (yydebug)                          \
+    yy_reduce_print (yyssp, yyvsp, Rule, arg); \
+} while (0)
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
    multiple parsers can coexist.  */
@@ -992,7 +888,7 @@ int yydebug;
 
 
 /* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef	YYINITDEPTH
+#ifndef YYINITDEPTH
 # define YYINITDEPTH 200
 #endif
 
@@ -1007,7 +903,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-

 
 #if YYERROR_VERBOSE
 
@@ -1016,15 +911,8 @@ int yydebug;
 #   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++)
@@ -1040,16 +928,8 @@ yystrlen (yystr)
 #  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;
@@ -1079,27 +959,27 @@ yytnamerr (char *yyres, const char *yystr)
       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;
-	  }
+        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: ;
     }
 
@@ -1110,163 +990,161 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # 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)
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
+
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
 {
-  int yyn = yypact[yystate];
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULLPTR;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
+    {
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          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 yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (! (yysize <= yysize1
+                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
+              }
+        }
+    }
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+  switch (yycount)
     {
-      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;
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
     }
+
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
+
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
+    }
+
+  /* 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 = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #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, parser_arg *arg)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep, arg)
-    const char *yymsg;
-    int yytype;
-    YYSTYPE *yyvaluep;
-    parser_arg *arg;
-#endif
 {
   YYUSE (yyvaluep);
   YYUSE (arg);
-
   if (!yymsg)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  switch (yytype)
-    {
-
-      default:
-	break;
-    }
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 }
 
-/* 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 (parser_arg *arg);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
+
 
 
 /* The lookahead symbol.  */
@@ -1274,49 +1152,26 @@ int yychar;
 
 /* The semantic value of the lookahead symbol.  */
 YYSTYPE yylval;
-
 /* Number of syntax errors so far.  */
 int yynerrs;
 
 
+/*----------.
+| yyparse.  |
+`----------*/
 
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
-
-#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 (parser_arg *arg)
-#else
-int
-yyparse (arg)
-    parser_arg *arg;
-#endif
-#endif
 {
-
-
     int yystate;
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
 
     /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
+       'yyss': related to states.
+       'yyvs': related to semantic values.
 
-       Refer to the stacks thru separate pointers, to allow yyoverflow
+       Refer to the stacks through separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
 
     /* The state stack.  */
@@ -1334,7 +1189,7 @@ yyparse (arg)
   int yyn;
   int yyresult;
   /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
+  int yytoken = 0;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
@@ -1352,9 +1207,8 @@ yyparse (arg)
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
   yystacksize = YYINITDEPTH;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1363,14 +1217,6 @@ yyparse (arg)
   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;
 
 /*------------------------------------------------------------.
@@ -1391,23 +1237,23 @@ yyparse (arg)
 
 #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;
+        /* 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
@@ -1415,22 +1261,22 @@ yyparse (arg)
 # else
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
-	goto yyexhaustedlab;
+        goto yyexhaustedlab;
       yystacksize *= 2;
       if (YYMAXDEPTH < yystacksize)
-	yystacksize = YYMAXDEPTH;
+        yystacksize = YYMAXDEPTH;
 
       {
-	yytype_int16 *yyss1 = yyss;
-	union yyalloc *yyptr =
-	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-	if (! yyptr)
-	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss_alloc, yyss);
-	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+        yytype_int16 *yyss1 = yyss;
+        union yyalloc *yyptr =
+          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+        if (! yyptr)
+          goto yyexhaustedlab;
+        YYSTACK_RELOCATE (yyss_alloc, yyss);
+        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
 #  undef YYSTACK_RELOCATE
-	if (yyss1 != yyssa)
-	  YYSTACK_FREE (yyss1);
+        if (yyss1 != yyssa)
+          YYSTACK_FREE (yyss1);
       }
 # endif
 #endif /* no yyoverflow */
@@ -1439,10 +1285,10 @@ yyparse (arg)
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-		  (unsigned long int) yystacksize));
+                  (unsigned long int) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
-	YYABORT;
+        YYABORT;
     }
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1462,7 +1308,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -1471,7 +1317,7 @@ yybackup:
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = YYLEX;
+      yychar = yylex ();
     }
 
   if (yychar <= YYEOF)
@@ -1493,8 +1339,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -1511,7 +1357,9 @@ yybackup:
   yychar = YYEMPTY;
 
   yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -1534,7 +1382,7 @@ yyreduce:
   yylen = yyr2[yyn];
 
   /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
+     '$$ = $1'.
 
      Otherwise, the following line sets YYVAL to garbage.
      This behavior is undocumented and Bison
@@ -1548,9 +1396,7 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-
-/* Line 1455 of yacc.c  */
-#line 194 "das.yy"
+#line 194 "das.yy" /* yacc.c:1646  */
     {
 		name = new string();
 		type = new string();
@@ -1558,181 +1404,158 @@ yyreduce:
 
 		// push outermost AttrTable
 		PUSH(DAS_OBJ(arg)->get_top_level_attributes());
-	;}
+	}
+#line 1409 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 3:
-
-/* Line 1455 of yacc.c  */
-#line 203 "das.yy"
+#line 203 "das.yy" /* yacc.c:1646  */
     {
 		POP;	// pop the DAS/AttrTable before stack's dtor
 		delete name;
 		delete type;
 		delete attr_tab_stack;
-	;}
+	}
+#line 1420 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 7:
-
-/* Line 1455 of yacc.c  */
-#line 218 "das.yy"
+#line 218 "das.yy" /* yacc.c:1646  */
     {
 		    parse_error((parser_arg *)arg, NO_DAS_MSG, das_line_num);
-		;}
+		}
+#line 1428 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 12:
-
-/* Line 1455 of yacc.c  */
-#line 230 "das.yy"
-    { save_str(*type, "Byte", das_line_num); ;}
+#line 230 "das.yy" /* yacc.c:1646  */
+    { save_str(*type, "Byte", das_line_num); }
+#line 1434 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 13:
-
-/* Line 1455 of yacc.c  */
-#line 231 "das.yy"
-    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+#line 231 "das.yy" /* yacc.c:1646  */
+    { save_str(*name, (yyvsp[0]), das_line_num); }
+#line 1440 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 15:
-
-/* Line 1455 of yacc.c  */
-#line 234 "das.yy"
-    { save_str(*type, "Int16", das_line_num); ;}
+#line 234 "das.yy" /* yacc.c:1646  */
+    { save_str(*type, "Int16", das_line_num); }
+#line 1446 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 16:
-
-/* Line 1455 of yacc.c  */
-#line 235 "das.yy"
-    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+#line 235 "das.yy" /* yacc.c:1646  */
+    { save_str(*name, (yyvsp[0]), das_line_num); }
+#line 1452 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 18:
-
-/* Line 1455 of yacc.c  */
-#line 238 "das.yy"
-    { save_str(*type, "UInt16", das_line_num); ;}
+#line 238 "das.yy" /* yacc.c:1646  */
+    { save_str(*type, "UInt16", das_line_num); }
+#line 1458 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 19:
-
-/* Line 1455 of yacc.c  */
-#line 239 "das.yy"
-    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+#line 239 "das.yy" /* yacc.c:1646  */
+    { save_str(*name, (yyvsp[0]), das_line_num); }
+#line 1464 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 21:
-
-/* Line 1455 of yacc.c  */
-#line 242 "das.yy"
-    { save_str(*type, "Int32", das_line_num); ;}
+#line 242 "das.yy" /* yacc.c:1646  */
+    { save_str(*type, "Int32", das_line_num); }
+#line 1470 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 22:
-
-/* Line 1455 of yacc.c  */
-#line 243 "das.yy"
-    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+#line 243 "das.yy" /* yacc.c:1646  */
+    { save_str(*name, (yyvsp[0]), das_line_num); }
+#line 1476 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 24:
-
-/* Line 1455 of yacc.c  */
-#line 246 "das.yy"
-    { save_str(*type, "UInt32", das_line_num); ;}
+#line 246 "das.yy" /* yacc.c:1646  */
+    { save_str(*type, "UInt32", das_line_num); }
+#line 1482 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 25:
-
-/* Line 1455 of yacc.c  */
-#line 247 "das.yy"
-    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+#line 247 "das.yy" /* yacc.c:1646  */
+    { save_str(*name, (yyvsp[0]), das_line_num); }
+#line 1488 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 27:
-
-/* Line 1455 of yacc.c  */
-#line 250 "das.yy"
-    { save_str(*type, "Float32", das_line_num); ;}
+#line 250 "das.yy" /* yacc.c:1646  */
+    { save_str(*type, "Float32", das_line_num); }
+#line 1494 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 28:
-
-/* Line 1455 of yacc.c  */
-#line 251 "das.yy"
-    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+#line 251 "das.yy" /* yacc.c:1646  */
+    { save_str(*name, (yyvsp[0]), das_line_num); }
+#line 1500 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 30:
-
-/* Line 1455 of yacc.c  */
-#line 254 "das.yy"
-    { save_str(*type, "Float64", das_line_num); ;}
+#line 254 "das.yy" /* yacc.c:1646  */
+    { save_str(*type, "Float64", das_line_num); }
+#line 1506 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 31:
-
-/* Line 1455 of yacc.c  */
-#line 255 "das.yy"
-    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+#line 255 "das.yy" /* yacc.c:1646  */
+    { save_str(*name, (yyvsp[0]), das_line_num); }
+#line 1512 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 33:
-
-/* Line 1455 of yacc.c  */
-#line 258 "das.yy"
-    { *type = "String"; ;}
+#line 258 "das.yy" /* yacc.c:1646  */
+    { *type = "String"; }
+#line 1518 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 34:
-
-/* Line 1455 of yacc.c  */
-#line 259 "das.yy"
-    { *name = (yyvsp[(3) - (3)]); ;}
+#line 259 "das.yy" /* yacc.c:1646  */
+    { *name = (yyvsp[0]); }
+#line 1524 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 36:
-
-/* Line 1455 of yacc.c  */
-#line 262 "das.yy"
-    { *type = "Url"; ;}
+#line 262 "das.yy" /* yacc.c:1646  */
+    { *type = "Url"; }
+#line 1530 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 37:
-
-/* Line 1455 of yacc.c  */
-#line 263 "das.yy"
-    { *name = (yyvsp[(3) - (3)]); ;}
+#line 263 "das.yy" /* yacc.c:1646  */
+    { *name = (yyvsp[0]); }
+#line 1536 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 39:
-
-/* Line 1455 of yacc.c  */
-#line 266 "das.yy"
-    { *type = "OtherXML"; ;}
+#line 266 "das.yy" /* yacc.c:1646  */
+    { *type = "OtherXML"; }
+#line 1542 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 40:
-
-/* Line 1455 of yacc.c  */
-#line 267 "das.yy"
-    { *name = (yyvsp[(3) - (3)]); ;}
+#line 267 "das.yy" /* yacc.c:1646  */
+    { *name = (yyvsp[0]); }
+#line 1548 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 42:
-
-/* Line 1455 of yacc.c  */
-#line 271 "das.yy"
+#line 271 "das.yy" /* yacc.c:1646  */
     {
-		    DBG(cerr << "Processing ID: " << (yyvsp[(1) - (1)]) << endl);
+		    DBG(cerr << "Processing ID: " << (yyvsp[0]) << endl);
 		    
-		    AttrTable *at = TOP_OF_STACK->get_attr_table((yyvsp[(1) - (1)]));
+		    AttrTable *at = TOP_OF_STACK->get_attr_table((yyvsp[0]));
 		    if (!at) {
 			try {
-			    at = TOP_OF_STACK->append_container((yyvsp[(1) - (1)]));
+			    at = TOP_OF_STACK->append_container((yyvsp[0]));
 			}
 			catch (Error &e) {
 			    // re-throw with line number info
@@ -1744,237 +1567,224 @@ yyreduce:
 
 		    DBG(cerr << " Pushed attr_tab: " << at << endl);
 
-		;}
+		}
+#line 1572 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 43:
-
-/* Line 1455 of yacc.c  */
-#line 291 "das.yy"
+#line 291 "das.yy" /* yacc.c:1646  */
     {
 		    /* pop top of stack; store in attr_tab */
 		    DBG(cerr << " Popped attr_tab: " << TOP_OF_STACK << endl);
 		    POP;
-		;}
+		}
+#line 1582 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 45:
-
-/* Line 1455 of yacc.c  */
-#line 299 "das.yy"
+#line 299 "das.yy" /* yacc.c:1646  */
     { 
-		    parse_error(ATTR_TUPLE_MSG, das_line_num, (yyvsp[(1) - (1)]));
-		;}
+		    parse_error(ATTR_TUPLE_MSG, das_line_num, (yyvsp[0]));
+		}
+#line 1590 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 47:
-
-/* Line 1455 of yacc.c  */
-#line 305 "das.yy"
+#line 305 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_byte);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_byte);
+		}
+#line 1598 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 48:
-
-/* Line 1455 of yacc.c  */
-#line 309 "das.yy"
+#line 309 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_byte);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_byte);
+		}
+#line 1606 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 49:
-
-/* Line 1455 of yacc.c  */
-#line 315 "das.yy"
+#line 315 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_int16);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_int16);
+		}
+#line 1614 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 50:
-
-/* Line 1455 of yacc.c  */
-#line 319 "das.yy"
+#line 319 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_int16);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_int16);
+		}
+#line 1622 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 51:
-
-/* Line 1455 of yacc.c  */
-#line 325 "das.yy"
+#line 325 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_uint16);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_uint16);
+		}
+#line 1630 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 52:
-
-/* Line 1455 of yacc.c  */
-#line 329 "das.yy"
+#line 329 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_uint16);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_uint16);
+		}
+#line 1638 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 53:
-
-/* Line 1455 of yacc.c  */
-#line 335 "das.yy"
+#line 335 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_int32);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_int32);
+		}
+#line 1646 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 54:
-
-/* Line 1455 of yacc.c  */
-#line 339 "das.yy"
+#line 339 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_int32);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_int32);
+		}
+#line 1654 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 55:
-
-/* Line 1455 of yacc.c  */
-#line 345 "das.yy"
+#line 345 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_uint32);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_uint32);
+		}
+#line 1662 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 56:
-
-/* Line 1455 of yacc.c  */
-#line 349 "das.yy"
+#line 349 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_uint32);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_uint32);
+		}
+#line 1670 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 57:
-
-/* Line 1455 of yacc.c  */
-#line 355 "das.yy"
+#line 355 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_float32);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_float32);
+		}
+#line 1678 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 58:
-
-/* Line 1455 of yacc.c  */
-#line 359 "das.yy"
+#line 359 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_float32);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_float32);
+		}
+#line 1686 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 59:
-
-/* Line 1455 of yacc.c  */
-#line 365 "das.yy"
+#line 365 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_float64);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_float64);
+		}
+#line 1694 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 60:
-
-/* Line 1455 of yacc.c  */
-#line 369 "das.yy"
+#line 369 "das.yy" /* yacc.c:1646  */
     {
-		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_float64);
-		;}
+		    add_attribute(*type, *name, (yyvsp[0]), &check_float64);
+		}
+#line 1702 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 61:
-
-/* Line 1455 of yacc.c  */
-#line 375 "das.yy"
+#line 375 "das.yy" /* yacc.c:1646  */
     {
-		    string attr = remove_quotes((yyvsp[(1) - (1)]));
+		    string attr = remove_quotes((yyvsp[0]));
 		    add_attribute(*type, *name, attr, 0);
-		;}
+		}
+#line 1711 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 62:
-
-/* Line 1455 of yacc.c  */
-#line 380 "das.yy"
+#line 380 "das.yy" /* yacc.c:1646  */
     {
-		    string attr = remove_quotes((yyvsp[(3) - (3)]));
+		    string attr = remove_quotes((yyvsp[0]));
 		    add_attribute(*type, *name, attr, 0);
-		;}
+		}
+#line 1720 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 63:
-
-/* Line 1455 of yacc.c  */
-#line 387 "das.yy"
+#line 387 "das.yy" /* yacc.c:1646  */
     {
-                    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_url);
-                ;}
+                    add_attribute(*type, *name, (yyvsp[0]), &check_url);
+                }
+#line 1728 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 64:
-
-/* Line 1455 of yacc.c  */
-#line 391 "das.yy"
+#line 391 "das.yy" /* yacc.c:1646  */
     {
-                    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_url);
-                ;}
+                    add_attribute(*type, *name, (yyvsp[0]), &check_url);
+                }
+#line 1736 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 65:
-
-/* Line 1455 of yacc.c  */
-#line 397 "das.yy"
+#line 397 "das.yy" /* yacc.c:1646  */
     {
                     // 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 << "Attr value as read: " << (yyvsp[0]) << endl;
+                    string xml = unescape_double_quotes((yyvsp[0]));
                     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);
-                ;}
+                }
+#line 1754 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 82:
-
-/* Line 1455 of yacc.c  */
-#line 427 "das.yy"
+#line 427 "das.yy" /* yacc.c:1646  */
     { 
-		    *name = (yyvsp[(2) - (2)]);
-		;}
+		    *name = (yyvsp[0]);
+		}
+#line 1762 "das.tab.cc" /* yacc.c:1646  */
     break;
 
   case 83:
-
-/* Line 1455 of yacc.c  */
-#line 431 "das.yy"
+#line 431 "das.yy" /* yacc.c:1646  */
     {
 		    add_alias( DAS_OBJ(arg)->get_top_level_attributes(),
-		               TOP_OF_STACK, *name, string((yyvsp[(4) - (4)])) ) ;
-                ;}
+		               TOP_OF_STACK, *name, string((yyvsp[0])) ) ;
+                }
+#line 1771 "das.tab.cc" /* yacc.c:1646  */
     break;
 
 
-
-/* Line 1455 of yacc.c  */
-#line 1976 "das.tab.cc"
+#line 1775 "das.tab.cc" /* yacc.c:1646  */
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -1983,7 +1793,7 @@ yyreduce:
 
   *++yyvsp = yyval;
 
-  /* Now `shift' the result of the reduction.  Determine what state
+  /* 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.  */
 
@@ -1998,10 +1808,14 @@ yyreduce:
   goto yynewstate;
 
 
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
+/*--------------------------------------.
+| yyerrlab -- here on detecting error.  |
+`--------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -2009,37 +1823,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (arg, YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-	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 (arg, yymsg);
-	  }
-	else
-	  {
-	    yyerror (arg, YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (arg, yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -2048,20 +1861,20 @@ yyerrlab:
   if (yyerrstatus == 3)
     {
       /* If just tried and failed to reuse lookahead token after an
-	 error, discard it.  */
+         error, discard it.  */
 
       if (yychar <= YYEOF)
-	{
-	  /* Return failure if at end of input.  */
-	  if (yychar == YYEOF)
-	    YYABORT;
-	}
+        {
+          /* Return failure if at end of input.  */
+          if (yychar == YYEOF)
+            YYABORT;
+        }
       else
-	{
-	  yydestruct ("Error: discarding",
-		      yytoken, &yylval, arg);
-	  yychar = YYEMPTY;
-	}
+        {
+          yydestruct ("Error: discarding",
+                      yytoken, &yylval, arg);
+          yychar = YYEMPTY;
+        }
     }
 
   /* Else will try to reuse lookahead token after shifting the error
@@ -2080,7 +1893,7 @@ yyerrorlab:
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-  /* Do not reclaim the symbols of the rule which action triggered
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
   yylen = 0;
@@ -2093,35 +1906,37 @@ yyerrorlab:
 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
 `-------------------------------------------------------------*/
 yyerrlab1:
-  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+  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;
-	    }
-	}
+      if (!yypact_value_is_default (yyn))
+        {
+          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;
+        YYABORT;
 
 
       yydestruct ("Error: popping",
-		  yystos[yystate], yyvsp, arg);
+                  yystos[yystate], yyvsp, arg);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
     }
 
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -2145,7 +1960,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -2157,16 +1972,21 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval, arg);
-  /* Do not reclaim the symbols of the rule which action triggered
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval, arg);
+    }
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
   YY_STACK_PRINT (yyss, yyssp);
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-		  yystos[*yyssp], yyvsp, arg);
+                  yystos[*yyssp], yyvsp, arg);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
@@ -2177,14 +1997,9 @@ yyreturn:
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
 #endif
-  /* Make sure YYID is used.  */
-  return YYID (yyresult);
+  return yyresult;
 }
-
-
-
-/* Line 1675 of yacc.c  */
-#line 438 "das.yy"
+#line 438 "das.yy" /* yacc.c:1906  */
 
 
 // This function is required for linking, but DODS uses its own error
@@ -2304,4 +2119,3 @@ add_bad_attribute(AttrTable *attr, const string &type, const string &name,
     }
 }
 
-
diff --git a/das.tab.hh b/das.tab.hh
index 9ea4caa..72782f5 100644
--- a/das.tab.hh
+++ b/das.tab.hh
@@ -1,21 +1,19 @@
+/* A Bison parser, made by GNU Bison 3.0.1.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* Bison interface for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
 
-/* 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 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 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/>.  */
 
@@ -28,14 +26,21 @@
    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.  */
 
+#ifndef YY_DAS_DAS_TAB_HH_INCLUDED
+# define YY_DAS_DAS_TAB_HH_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int dasdebug;
+#endif
 /* "%code requires" blocks.  */
-
-/* Line 1676 of yacc.c  */
-#line 40 "das.yy"
+#line 40 "das.yy" /* yacc.c:1909  */
 
 
 #define YYSTYPE char *
@@ -54,7 +59,7 @@
 #include "debug.h"
 #include "parser.h"
 #include "util.h"
-  // #include "das.tab.hh"
+// #include "das.tab.hh"
 
 #ifdef TRACE_NEW
 #include "trace_new.h"
@@ -80,42 +85,39 @@ using namespace libdap ;
 extern int das_line_num;	/* defined in das.lex */
 
 
+#line 89 "das.tab.hh" /* yacc.c:1909  */
 
-
-/* Line 1676 of yacc.c  */
-#line 87 "das.tab.hh"
-
-/* Tokens.  */
+/* Token type.  */
 #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
-   };
+  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
 
-
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef int YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
+
 extern YYSTYPE daslval;
 
+int dasparse (parser_arg *arg);
 
+#endif /* !YY_DAS_DAS_TAB_HH_INCLUDED  */
diff --git a/das.yy b/das.yy
index a85f573..5b2c618 100644
--- a/das.yy
+++ b/das.yy
@@ -55,7 +55,7 @@
 #include "debug.h"
 #include "parser.h"
 #include "util.h"
-  // #include "das.tab.hh"
+// #include "das.tab.hh"
 
 #ifdef TRACE_NEW
 #include "trace_new.h"
diff --git a/dds.tab.cc b/dds.tab.cc
index 7580858..c599be5 100644
--- a/dds.tab.cc
+++ b/dds.tab.cc
@@ -1,21 +1,19 @@
+/* A Bison parser, made by GNU Bison 3.0.1.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* Bison implementation for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
 
-/* 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 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 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/>.  */
 
@@ -28,7 +26,7 @@
    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.  */
 
@@ -46,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "3.0.1"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -60,29 +58,28 @@
 /* Pull parsers.  */
 #define YYPULL 1
 
-/* 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
 
+#define yylval          ddslval
+#define yychar          ddschar
 
 /* Copy the first part of user declarations.  */
 
+#line 75 "dds.tab.cc" /* yacc.c:339  */
 
-/* Line 189 of yacc.c  */
-#line 81 "dds.tab.cc"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -92,15 +89,19 @@
 # define YYERROR_VERBOSE 0
 #endif
 
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+   by #include "dds.tab.hh".  */
+#ifndef YY_DDS_DDS_TAB_HH_INCLUDED
+# define YY_DDS_DDS_TAB_HH_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int ddsdebug;
 #endif
-
 /* "%code requires" blocks.  */
-
-/* Line 209 of yacc.c  */
-#line 47 "dds.yy"
+#line 47 "dds.yy" /* yacc.c:355  */
 
 
 #include "config_dap.h"
@@ -146,68 +147,60 @@ using namespace libdap;
 extern int dds_line_num;	/* defined in dds.lex */
 
 
+#line 151 "dds.tab.cc" /* yacc.c:355  */
 
-
-/* Line 209 of yacc.c  */
-#line 153 "dds.tab.cc"
-
-/* Tokens.  */
+/* Token type.  */
 #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
-   };
+  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
 
-
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
 {
-
-/* Line 214 of yacc.c  */
-#line 131 "dds.yy"
+#line 131 "dds.yy" /* yacc.c:355  */
 
     bool boolean;
     char word[ID_MAX];
 
-
-
-/* Line 214 of yacc.c  */
-#line 195 "dds.tab.cc"
-} YYSTYPE;
+#line 187 "dds.tab.cc" /* yacc.c:355  */
+};
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
 
-/* Copy the second part of user declarations.  */
+extern YYSTYPE ddslval;
 
+int ddsparse (parser_arg *arg);
 
-/* Line 264 of yacc.c  */
-#line 207 "dds.tab.cc"
-/* Unqualified %code blocks.  */
+#endif /* !YY_DDS_DDS_TAB_HH_INCLUDED  */
 
-/* Line 265 of yacc.c  */
-#line 93 "dds.yy"
+/* Copy the second part of user declarations.  */
+
+#line 202 "dds.tab.cc" /* yacc.c:358  */
+/* Unqualified %code blocks.  */
+#line 93 "dds.yy" /* yacc.c:359  */
 
 
 // No global static objects in the dap library! 1/24/2000 jhrg
@@ -235,10 +228,7 @@ void invalid_declaration(parser_arg *arg, string semantic_err_msg,
 			 char *type, char *name);
 
 
-
-
-/* Line 265 of yacc.c  */
-#line 242 "dds.tab.cc"
+#line 232 "dds.tab.cc" /* yacc.c:359  */
 
 #ifdef short
 # undef short
@@ -252,11 +242,8 @@ typedef unsigned char yytype_uint8;
 
 #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;
+typedef signed char yytype_int8;
 #endif
 
 #ifdef YYTYPE_UINT16
@@ -276,8 +263,7 @@ typedef short int yytype_int16;
 #  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)
+# elif ! defined YYSIZE_T
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
@@ -288,42 +274,71 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(msgid) msgid
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
 #else
-# define YYUSE(e) /* empty */
+# 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 yyi)
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
 #else
-static int
-YYID (yyi)
-    int yyi;
+# define YY_INITIAL_VALUE(Value) Value
 #endif
-{
-  return yyi;
-}
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
 #endif
 
+
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */
@@ -341,11 +356,11 @@ YYID (yyi)
 #    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)
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -353,8 +368,8 @@ YYID (yyi)
 # endif
 
 # ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+   /* Pacify GCC's 'empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (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
@@ -368,25 +383,23 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
-	     && (defined YYFREE || defined free)))
+             && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
+#   if ! defined malloc && ! defined EXIT_SUCCESS
 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)
+#   if ! defined free && ! defined EXIT_SUCCESS
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
@@ -396,7 +409,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
-	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
@@ -414,42 +427,46 @@ union yyalloc
      ((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
+# define YYCOPY_NEEDED 1
 
 /* 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_alloc, Stack)				\
-    do									\
-      {									\
-	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
-	Stack = &yyptr->Stack_alloc;					\
-	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-	yyptr += yynewbytes / sizeof (*yyptr);				\
-      }									\
-    while (YYID (0))
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
+    do                                                                  \
+      {                                                                 \
+        YYSIZE_T yynewbytes;                                            \
+        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+        Stack = &yyptr->Stack_alloc;                                    \
+        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                 \
+    while (0)
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (0)
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
@@ -461,17 +478,19 @@ union yyalloc
 #define YYNNTS  22
 /* YYNRULES -- Number of rules.  */
 #define YYNRULES  56
-/* YYNRULES -- Number of states.  */
+/* YYNSTATES -- Number of states.  */
 #define YYNSTATES  88
 
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   273
 
-#define YYTRANSLATE(YYX)						\
+#define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, without out-of-bounds checking.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -505,39 +524,7 @@ static const yytype_uint8 yytranslate[] =
 };
 
 #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.  */
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
        0,   160,   160,   160,   170,   171,   174,   178,   188,   192,
@@ -549,7 +536,7 @@ static const yytype_uint16 yyrline[] =
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
@@ -561,13 +548,13 @@ static const char *const yytname[] =
   "';'", "':'", "'['", "']'", "'='", "$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
+  "array_decl", "$@7", "$@8", "name", YY_NULLPTR
 };
 #endif
 
 # ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+   (internal) symbol number NUM (which must be that of a token).  */
 static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
@@ -576,55 +563,18 @@ static const yytype_uint16 yytoknum[] =
 };
 # 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
-};
+#define YYPACT_NINF -53
 
-/* 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
-};
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-53)))
 
-/* 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
-};
+#define YYTABLE_NINF -9
 
-/* 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
-};
+#define yytable_value_is_error(Yytable_value) \
+  0
 
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -53
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
      -53,    11,     9,   -53,   -53,    -7,     5,   -53,    52,   -53,
@@ -638,7 +588,23 @@ static const yytype_int16 yypact[] =
       14,    52,   -53,   124,   -53,   176,     7,   -53
 };
 
-/* YYPGOTO[NTERM-NUM].  */
+  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+     Performed when YYTABLE does not 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
+};
+
+  /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
      -53,   -53,   -53,   -53,    35,   -30,   -23,   -53,   -53,   -53,
@@ -646,11 +612,17 @@ static const yytype_int8 yypgoto[] =
      -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
+  /* 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
+};
+
+  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule whose
+     number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int8 yytable[] =
 {
       30,    54,    55,    57,    57,    -3,     4,    57,    57,     5,
@@ -699,8 +671,8 @@ static const yytype_int8 yycheck[] =
       14,    15,    16,    17,    18
 };
 
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
+  /* 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,
@@ -714,95 +686,63 @@ static const yytype_uint8 yystos[] =
       46,    36,    24,    31,    20,    37,    42,    21
 };
 
-#define yyerrok		(yyerrstatus = 0)
-#define yyclearin	(yychar = YYEMPTY)
-#define YYEMPTY		(-2)
-#define YYEOF		0
+  /* 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 on the 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
+};
 
-#define YYACCEPT	goto yyacceptlab
-#define YYABORT		goto yyabortlab
-#define YYERROR		goto yyerrorlab
 
+#define yyerrok         (yyerrstatus = 0)
+#define yyclearin       (yychar = YYEMPTY)
+#define YYEMPTY         (-2)
+#define YYEOF           0
 
-/* 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 YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
 
-#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								\
-    {								\
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
       yyerror (arg, 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
+      YYERROR;                                                  \
+    }                                                           \
+while (0)
 
+/* Error token number */
+#define YYTERROR        1
+#define YYERRCODE       256
 
-/* 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
@@ -812,56 +752,47 @@ while (YYID (0))
 #  define YYFPRINTF fprintf
 # endif
 
-# define YYDPRINTF(Args)			\
-do {						\
-  if (yydebug)					\
-    YYFPRINTF Args;				\
-} while (YYID (0))
+# define YYDPRINTF(Args)                        \
+do {                                            \
+  if (yydebug)                                  \
+    YYFPRINTF Args;                             \
+} while (0)
 
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
-do {									  \
-  if (yydebug)								  \
-    {									  \
-      YYFPRINTF (stderr, "%s ", Title);					  \
-      yy_symbol_print (stderr,						  \
-		  Type, Value, arg); \
-      YYFPRINTF (stderr, "\n");						  \
-    }									  \
-} while (YYID (0))
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
+do {                                                                      \
+  if (yydebug)                                                            \
+    {                                                                     \
+      YYFPRINTF (stderr, "%s ", Title);                                   \
+      yy_symbol_print (stderr,                                            \
+                  Type, Value, arg); \
+      YYFPRINTF (stderr, "\n");                                           \
+    }                                                                     \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value 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, parser_arg *arg)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    parser_arg *arg;
-#endif
 {
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
+  YYUSE (arg);
   if (!yyvaluep)
     return;
-  YYUSE (arg);
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
-  YYUSE (yyoutput);
 # endif
-  switch (yytype)
-    {
-      default:
-	break;
-    }
+  YYUSE (yytype);
 }
 
 
@@ -869,23 +800,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg)
 | 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, parser_arg *arg)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, arg)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    parser_arg *arg;
-#endif
 {
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-  else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+  YYFPRINTF (yyoutput, "%s %s (",
+             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
   yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg);
   YYFPRINTF (yyoutput, ")");
@@ -896,16 +815,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, arg)
 | TOP (included).                                                   |
 `------------------------------------------------------------------*/
 
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
-#endif
 {
   YYFPRINTF (stderr, "Stack now");
   for (; yybottom <= yytop; yybottom++)
@@ -916,50 +827,42 @@ yy_stack_print (yybottom, yytop)
   YYFPRINTF (stderr, "\n");
 }
 
-# define YY_STACK_PRINT(Bottom, Top)				\
-do {								\
-  if (yydebug)							\
-    yy_stack_print ((Bottom), (Top));				\
-} while (YYID (0))
+# define YY_STACK_PRINT(Bottom, Top)                            \
+do {                                                            \
+  if (yydebug)                                                  \
+    yy_stack_print ((Bottom), (Top));                           \
+} while (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, parser_arg *arg)
-#else
 static void
-yy_reduce_print (yyvsp, yyrule, arg)
-    YYSTYPE *yyvsp;
-    int yyrule;
-    parser_arg *arg;
-#endif
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, parser_arg *arg)
 {
+  unsigned long int yylno = yyrline[yyrule];
   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);
+             yyrule - 1, yylno);
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
-		       &(yyvsp[(yyi + 1) - (yynrhs)])
-		       		       , arg);
+      yy_symbol_print (stderr,
+                       yystos[yyssp[yyi + 1 - yynrhs]],
+                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                                              , arg);
       YYFPRINTF (stderr, "\n");
     }
 }
 
-# define YY_REDUCE_PRINT(Rule)		\
-do {					\
-  if (yydebug)				\
-    yy_reduce_print (yyvsp, Rule, arg); \
-} while (YYID (0))
+# define YY_REDUCE_PRINT(Rule)          \
+do {                                    \
+  if (yydebug)                          \
+    yy_reduce_print (yyssp, yyvsp, Rule, arg); \
+} while (0)
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
    multiple parsers can coexist.  */
@@ -973,7 +876,7 @@ int yydebug;
 
 
 /* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef	YYINITDEPTH
+#ifndef YYINITDEPTH
 # define YYINITDEPTH 200
 #endif
 
@@ -988,7 +891,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-

 
 #if YYERROR_VERBOSE
 
@@ -997,15 +899,8 @@ int yydebug;
 #   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++)
@@ -1021,16 +916,8 @@ yystrlen (yystr)
 #  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;
@@ -1060,27 +947,27 @@ yytnamerr (char *yyres, const char *yystr)
       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;
-	  }
+        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: ;
     }
 
@@ -1091,163 +978,161 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # 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)
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
+
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
 {
-  int yyn = yypact[yystate];
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULLPTR;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
+    {
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          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 yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (! (yysize <= yysize1
+                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
+              }
+        }
+    }
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+  switch (yycount)
     {
-      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;
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
+
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
+
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
     }
+
+  /* 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 = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #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, parser_arg *arg)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep, arg)
-    const char *yymsg;
-    int yytype;
-    YYSTYPE *yyvaluep;
-    parser_arg *arg;
-#endif
 {
   YYUSE (yyvaluep);
   YYUSE (arg);
-
   if (!yymsg)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  switch (yytype)
-    {
-
-      default:
-	break;
-    }
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 }
 
-/* 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 (parser_arg *arg);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
+
 
 
 /* The lookahead symbol.  */
@@ -1255,49 +1140,26 @@ int yychar;
 
 /* The semantic value of the lookahead symbol.  */
 YYSTYPE yylval;
-
 /* Number of syntax errors so far.  */
 int yynerrs;
 
 
+/*----------.
+| yyparse.  |
+`----------*/
 
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
-
-#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 (parser_arg *arg)
-#else
-int
-yyparse (arg)
-    parser_arg *arg;
-#endif
-#endif
 {
-
-
     int yystate;
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
 
     /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
+       'yyss': related to states.
+       'yyvs': related to semantic values.
 
-       Refer to the stacks thru separate pointers, to allow yyoverflow
+       Refer to the stacks through separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
 
     /* The state stack.  */
@@ -1315,7 +1177,7 @@ yyparse (arg)
   int yyn;
   int yyresult;
   /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
+  int yytoken = 0;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
@@ -1333,9 +1195,8 @@ yyparse (arg)
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
   yystacksize = YYINITDEPTH;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1344,14 +1205,6 @@ yyparse (arg)
   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;
 
 /*------------------------------------------------------------.
@@ -1372,23 +1225,23 @@ yyparse (arg)
 
 #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;
+        /* 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
@@ -1396,22 +1249,22 @@ yyparse (arg)
 # else
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
-	goto yyexhaustedlab;
+        goto yyexhaustedlab;
       yystacksize *= 2;
       if (YYMAXDEPTH < yystacksize)
-	yystacksize = YYMAXDEPTH;
+        yystacksize = YYMAXDEPTH;
 
       {
-	yytype_int16 *yyss1 = yyss;
-	union yyalloc *yyptr =
-	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-	if (! yyptr)
-	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss_alloc, yyss);
-	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+        yytype_int16 *yyss1 = yyss;
+        union yyalloc *yyptr =
+          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+        if (! yyptr)
+          goto yyexhaustedlab;
+        YYSTACK_RELOCATE (yyss_alloc, yyss);
+        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
 #  undef YYSTACK_RELOCATE
-	if (yyss1 != yyssa)
-	  YYSTACK_FREE (yyss1);
+        if (yyss1 != yyssa)
+          YYSTACK_FREE (yyss1);
       }
 # endif
 #endif /* no yyoverflow */
@@ -1420,10 +1273,10 @@ yyparse (arg)
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-		  (unsigned long int) yystacksize));
+                  (unsigned long int) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
-	YYABORT;
+        YYABORT;
     }
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1443,7 +1296,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -1452,7 +1305,7 @@ yybackup:
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = YYLEX;
+      yychar = yylex ();
     }
 
   if (yychar <= YYEOF)
@@ -1474,8 +1327,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -1492,7 +1345,9 @@ yybackup:
   yychar = YYEMPTY;
 
   yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -1515,7 +1370,7 @@ yyreduce:
   yylen = yyr2[yyn];
 
   /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
+     '$$ = $1'.
 
      Otherwise, the following line sets YYVAL to garbage.
      This behavior is undocumented and Bison
@@ -1529,72 +1384,63 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-
-/* Line 1455 of yacc.c  */
-#line 160 "dds.yy"
+#line 160 "dds.yy" /* yacc.c:1646  */
     {
 		    /* On entry to the parser, make the BaseType stack. */
 		    ctor = new stack<BaseType *>;
-                ;}
+                }
+#line 1393 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 3:
-
-/* Line 1455 of yacc.c  */
-#line 165 "dds.yy"
+#line 165 "dds.yy" /* yacc.c:1646  */
     {
 		    delete ctor; ctor = 0;
-		;}
+		}
+#line 1401 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 6:
-
-/* Line 1455 of yacc.c  */
-#line 175 "dds.yy"
+#line 175 "dds.yy" /* yacc.c:1646  */
     {
-		    (yyval.boolean) = (yyvsp[(3) - (6)].boolean) && (yyvsp[(5) - (6)].word);
-		;}
+		    (yyval.boolean) = (yyvsp[-3].boolean) && (yyvsp[-1].word);
+		}
+#line 1409 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 7:
-
-/* Line 1455 of yacc.c  */
-#line 179 "dds.yy"
+#line 179 "dds.yy" /* yacc.c:1646  */
     {
 		    parse_error((parser_arg *)arg, NO_DDS_MSG,
- 				dds_line_num, (yyvsp[(1) - (1)].word));
+ 				dds_line_num, (yyvsp[0].word));
 		    error_exit_cleanup();
 		    YYABORT;
-		;}
+		}
+#line 1420 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 8:
-
-/* Line 1455 of yacc.c  */
-#line 188 "dds.yy"
+#line 188 "dds.yy" /* yacc.c:1646  */
     {
 		    (yyval.boolean) = true;
-		;}
+		}
+#line 1428 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 9:
-
-/* Line 1455 of yacc.c  */
-#line 192 "dds.yy"
-    { (yyval.boolean) = true; ;}
+#line 192 "dds.yy" /* yacc.c:1646  */
+    { (yyval.boolean) = true; }
+#line 1434 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 10:
-
-/* Line 1455 of yacc.c  */
-#line 193 "dds.yy"
-    { (yyval.boolean) = true; ;}
+#line 193 "dds.yy" /* yacc.c:1646  */
+    { (yyval.boolean) = true; }
+#line 1440 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 11:
-
-/* Line 1455 of yacc.c  */
-#line 201 "dds.yy"
+#line 201 "dds.yy" /* yacc.c:1646  */
     { 
 		    string smsg;
 		    if (current->check_semantics(smsg)) {
@@ -1608,122 +1454,114 @@ yyreduce:
 			}
 			*/
 		    } else {
-		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[(1) - (3)].word), (yyvsp[(2) - (3)].word));
+		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[-2].word), (yyvsp[-1].word));
 		      error_exit_cleanup();
 		      YYABORT;
 		    }
-                    strncpy((yyval.word),(yyvsp[(2) - (3)].word),ID_MAX);
+                    strncpy((yyval.word),(yyvsp[-1].word),ID_MAX);
                     (yyval.word)[ID_MAX-1] = '\0';
-		;}
+		}
+#line 1465 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 12:
-
-/* Line 1455 of yacc.c  */
-#line 223 "dds.yy"
+#line 223 "dds.yy" /* yacc.c:1646  */
     { 
 		    if( current ) delete current ;
 		    current = ctor->top(); 
 		    ctor->pop();
-		;}
+		}
+#line 1475 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 13:
-
-/* Line 1455 of yacc.c  */
-#line 229 "dds.yy"
+#line 229 "dds.yy" /* yacc.c:1646  */
     { 
 		    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));
+		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[-6].word), (yyvsp[-1].word));
 		      error_exit_cleanup();
 		      YYABORT;
 		    }
-                    strncpy((yyval.word),(yyvsp[(6) - (7)].word),ID_MAX);
+                    strncpy((yyval.word),(yyvsp[-1].word),ID_MAX);
                     (yyval.word)[ID_MAX-1] = '\0';
-		;}
+		}
+#line 1492 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 14:
-
-/* Line 1455 of yacc.c  */
-#line 243 "dds.yy"
+#line 243 "dds.yy" /* yacc.c:1646  */
     { 
 		    if( current ) delete current ;
 		    current = ctor->top(); 
 		    ctor->pop();
-		;}
+		}
+#line 1502 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 15:
-
-/* Line 1455 of yacc.c  */
-#line 249 "dds.yy"
+#line 249 "dds.yy" /* yacc.c:1646  */
     { 
 		    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));
+		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[-6].word), (yyvsp[-1].word));
 		      error_exit_cleanup();
 		      YYABORT;
 		    }
-                    strncpy((yyval.word),(yyvsp[(6) - (7)].word),ID_MAX);
+                    strncpy((yyval.word),(yyvsp[-1].word),ID_MAX);
                     (yyval.word)[ID_MAX-1] = '\0';
-		;}
+		}
+#line 1519 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 16:
-
-/* Line 1455 of yacc.c  */
-#line 263 "dds.yy"
+#line 263 "dds.yy" /* yacc.c:1646  */
     { 
-		    if (is_keyword(string((yyvsp[(3) - (4)].word)), "array"))
+		    if (is_keyword(string((yyvsp[-1].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));
+				    dds_line_num, (yyvsp[-1].word));
 			YYABORT;
 		    }
-                ;}
+                }
+#line 1535 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 17:
-
-/* Line 1455 of yacc.c  */
-#line 275 "dds.yy"
+#line 275 "dds.yy" /* yacc.c:1646  */
     { 
-		    if (is_keyword(string((yyvsp[(7) - (8)].word)), "maps"))
+		    if (is_keyword(string((yyvsp[-1].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));
+				    dds_line_num, (yyvsp[-1].word));
 			YYABORT;
 		    }
-                ;}
+                }
+#line 1551 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 18:
-
-/* Line 1455 of yacc.c  */
-#line 287 "dds.yy"
+#line 287 "dds.yy" /* yacc.c:1646  */
     {
 		    if( current ) delete current ;
 		    current = ctor->top(); 
 		    ctor->pop();
-		;}
+		}
+#line 1561 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 19:
-
-/* Line 1455 of yacc.c  */
-#line 293 "dds.yy"
+#line 293 "dds.yy" /* yacc.c:1646  */
     {
 		    string smsg;
 		    if (current->check_semantics(smsg)) {
@@ -1731,246 +1569,234 @@ yyreduce:
 			add_entry(*DDS_OBJ(arg), &ctor, &current, part); 
 		    }
 		    else {
-		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[(1) - (14)].word), (yyvsp[(13) - (14)].word));
+		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[-13].word), (yyvsp[-1].word));
 		      error_exit_cleanup();
 		      YYABORT;
 		    }
-                    strncpy((yyval.word),(yyvsp[(13) - (14)].word),ID_MAX);
+                    strncpy((yyval.word),(yyvsp[-1].word),ID_MAX);
                     (yyval.word)[ID_MAX-1] = '\0';
-		;}
+		}
+#line 1580 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 20:
-
-/* Line 1455 of yacc.c  */
-#line 309 "dds.yy"
+#line 309 "dds.yy" /* yacc.c:1646  */
     {
 		    ostringstream msg;
 		    msg << BAD_DECLARATION;
 		    parse_error((parser_arg *)arg, msg.str().c_str(),
-				dds_line_num, (yyvsp[(1) - (1)].word));
+				dds_line_num, (yyvsp[0].word));
 		    YYABORT;
-		;}
+		}
+#line 1592 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 21:
-
-/* Line 1455 of yacc.c  */
-#line 320 "dds.yy"
+#line 320 "dds.yy" /* yacc.c:1646  */
     { 
 		    ctor->push(DDS_OBJ(arg)->get_factory()->NewStructure()); 
-		;}
+		}
+#line 1600 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 22:
-
-/* Line 1455 of yacc.c  */
-#line 326 "dds.yy"
+#line 326 "dds.yy" /* yacc.c:1646  */
     { 
 		    ctor->push(DDS_OBJ(arg)->get_factory()->NewSequence()); 
-		;}
+		}
+#line 1608 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 23:
-
-/* Line 1455 of yacc.c  */
-#line 332 "dds.yy"
+#line 332 "dds.yy" /* yacc.c:1646  */
     { 
 		    ctor->push(DDS_OBJ(arg)->get_factory()->NewGrid()); 
-		;}
+		}
+#line 1616 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 24:
-
-/* Line 1455 of yacc.c  */
-#line 337 "dds.yy"
-    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewByte(); ;}
+#line 337 "dds.yy" /* yacc.c:1646  */
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewByte(); }
+#line 1622 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 25:
-
-/* Line 1455 of yacc.c  */
-#line 338 "dds.yy"
-    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt16(); ;}
+#line 338 "dds.yy" /* yacc.c:1646  */
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt16(); }
+#line 1628 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 26:
-
-/* Line 1455 of yacc.c  */
-#line 339 "dds.yy"
-    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt16(); ;}
+#line 339 "dds.yy" /* yacc.c:1646  */
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt16(); }
+#line 1634 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 27:
-
-/* Line 1455 of yacc.c  */
-#line 340 "dds.yy"
-    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt32(); ;}
+#line 340 "dds.yy" /* yacc.c:1646  */
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt32(); }
+#line 1640 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 28:
-
-/* Line 1455 of yacc.c  */
-#line 341 "dds.yy"
-    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt32(); ;}
+#line 341 "dds.yy" /* yacc.c:1646  */
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt32(); }
+#line 1646 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 29:
-
-/* Line 1455 of yacc.c  */
-#line 342 "dds.yy"
-    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat32(); ;}
+#line 342 "dds.yy" /* yacc.c:1646  */
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat32(); }
+#line 1652 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 30:
-
-/* Line 1455 of yacc.c  */
-#line 343 "dds.yy"
-    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat64(); ;}
+#line 343 "dds.yy" /* yacc.c:1646  */
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat64(); }
+#line 1658 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 31:
-
-/* Line 1455 of yacc.c  */
-#line 344 "dds.yy"
-    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewStr(); ;}
+#line 344 "dds.yy" /* yacc.c:1646  */
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewStr(); }
+#line 1664 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 32:
-
-/* Line 1455 of yacc.c  */
-#line 345 "dds.yy"
-    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUrl(); ;}
+#line 345 "dds.yy" /* yacc.c:1646  */
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUrl(); }
+#line 1670 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 33:
-
-/* Line 1455 of yacc.c  */
-#line 348 "dds.yy"
-    { current->set_name((yyvsp[(1) - (1)].word)); ;}
+#line 348 "dds.yy" /* yacc.c:1646  */
+    { current->set_name((yyvsp[0].word)); }
+#line 1676 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 49:
-
-/* Line 1455 of yacc.c  */
-#line 359 "dds.yy"
+#line 359 "dds.yy" /* yacc.c:1646  */
     { 
-		     if (!check_int32((yyvsp[(2) - (3)].word))) {
+		     if (!check_int32((yyvsp[-1].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));
+				 dds_line_num, (yyvsp[-1].word));
 		     }
 		     if (current->type() == dods_array_c
-			 && check_int32((yyvsp[(2) - (3)].word))) {
-			 ((Array *)current)->append_dim(atoi((yyvsp[(2) - (3)].word)));
+			 && check_int32((yyvsp[-1].word))) {
+			 ((Array *)current)->append_dim(atoi((yyvsp[-1].word)));
 		     }
 		     else {
 			 Array *a = DDS_OBJ(arg)->get_factory()->NewArray(); 
 			 a->add_var(current); 
-			 a->append_dim(atoi((yyvsp[(2) - (3)].word)));
+			 a->append_dim(atoi((yyvsp[-1].word)));
 			 if( current ) delete current ;
 			 current = a;
 		     }
 
 		     (yyval.boolean) = true;
-		 ;}
+		 }
+#line 1702 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 50:
-
-/* Line 1455 of yacc.c  */
-#line 382 "dds.yy"
+#line 382 "dds.yy" /* yacc.c:1646  */
     {
-		     id = new string((yyvsp[(2) - (2)].word));
-		 ;}
+		     id = new string((yyvsp[0].word));
+		 }
+#line 1710 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 51:
-
-/* Line 1455 of yacc.c  */
-#line 386 "dds.yy"
+#line 386 "dds.yy" /* yacc.c:1646  */
     { 
-		     if (!check_int32((yyvsp[(5) - (5)].word))) {
+		     if (!check_int32((yyvsp[0].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));
+				 dds_line_num, (yyvsp[0].word));
 			 error_exit_cleanup();
 			 YYABORT;
 		     }
 		     if (current->type() == dods_array_c) {
-			 ((Array *)current)->append_dim(atoi((yyvsp[(5) - (5)].word)), *id);
+			 ((Array *)current)->append_dim(atoi((yyvsp[0].word)), *id);
 		     }
 		     else {
 			 Array *a = DDS_OBJ(arg)->get_factory()->NewArray(); 
 			 a->add_var(current); 
-			 a->append_dim(atoi((yyvsp[(5) - (5)].word)), *id);
+			 a->append_dim(atoi((yyvsp[0].word)), *id);
 			 if( current ) delete current ;
 			 current = a;
 		     }
 
 		     delete id; id = 0;
-		 ;}
+		 }
+#line 1737 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 52:
-
-/* Line 1455 of yacc.c  */
-#line 409 "dds.yy"
+#line 409 "dds.yy" /* yacc.c:1646  */
     {
 		     (yyval.boolean) = true;
-		 ;}
+		 }
+#line 1745 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 53:
-
-/* Line 1455 of yacc.c  */
-#line 414 "dds.yy"
+#line 414 "dds.yy" /* yacc.c:1646  */
     {
 		     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));
+				 dds_line_num, (yyvsp[0].word));
 		     YYABORT;
-		 ;}
+		 }
+#line 1758 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 54:
-
-/* Line 1455 of yacc.c  */
-#line 424 "dds.yy"
-    { (*DDS_OBJ(arg)).set_dataset_name((yyvsp[(1) - (1)].word)); ;}
+#line 424 "dds.yy" /* yacc.c:1646  */
+    { (*DDS_OBJ(arg)).set_dataset_name((yyvsp[0].word)); }
+#line 1764 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 55:
-
-/* Line 1455 of yacc.c  */
-#line 425 "dds.yy"
-    { (*DDS_OBJ(arg)).set_dataset_name((yyvsp[(1) - (1)].word)); ;}
+#line 425 "dds.yy" /* yacc.c:1646  */
+    { (*DDS_OBJ(arg)).set_dataset_name((yyvsp[0].word)); }
+#line 1770 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
   case 56:
-
-/* Line 1455 of yacc.c  */
-#line 427 "dds.yy"
+#line 427 "dds.yy" /* yacc.c:1646  */
     {
 		  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));
+				 dds_line_num, (yyvsp[0].word));
 		     YYABORT;
-		;}
+		}
+#line 1783 "dds.tab.cc" /* yacc.c:1646  */
     break;
 
 
-
-/* Line 1455 of yacc.c  */
-#line 1972 "dds.tab.cc"
+#line 1787 "dds.tab.cc" /* yacc.c:1646  */
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -1979,7 +1805,7 @@ yyreduce:
 
   *++yyvsp = yyval;
 
-  /* Now `shift' the result of the reduction.  Determine what state
+  /* 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.  */
 
@@ -1994,10 +1820,14 @@ yyreduce:
   goto yynewstate;
 
 
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
+/*--------------------------------------.
+| yyerrlab -- here on detecting error.  |
+`--------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -2005,37 +1835,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (arg, YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-	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 (arg, yymsg);
-	  }
-	else
-	  {
-	    yyerror (arg, YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (arg, yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -2044,20 +1873,20 @@ yyerrlab:
   if (yyerrstatus == 3)
     {
       /* If just tried and failed to reuse lookahead token after an
-	 error, discard it.  */
+         error, discard it.  */
 
       if (yychar <= YYEOF)
-	{
-	  /* Return failure if at end of input.  */
-	  if (yychar == YYEOF)
-	    YYABORT;
-	}
+        {
+          /* Return failure if at end of input.  */
+          if (yychar == YYEOF)
+            YYABORT;
+        }
       else
-	{
-	  yydestruct ("Error: discarding",
-		      yytoken, &yylval, arg);
-	  yychar = YYEMPTY;
-	}
+        {
+          yydestruct ("Error: discarding",
+                      yytoken, &yylval, arg);
+          yychar = YYEMPTY;
+        }
     }
 
   /* Else will try to reuse lookahead token after shifting the error
@@ -2076,7 +1905,7 @@ yyerrorlab:
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-  /* Do not reclaim the symbols of the rule which action triggered
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
   yylen = 0;
@@ -2089,35 +1918,37 @@ yyerrorlab:
 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
 `-------------------------------------------------------------*/
 yyerrlab1:
-  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+  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;
-	    }
-	}
+      if (!yypact_value_is_default (yyn))
+        {
+          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;
+        YYABORT;
 
 
       yydestruct ("Error: popping",
-		  yystos[yystate], yyvsp, arg);
+                  yystos[yystate], yyvsp, arg);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
     }
 
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -2141,7 +1972,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -2153,16 +1984,21 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval, arg);
-  /* Do not reclaim the symbols of the rule which action triggered
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval, arg);
+    }
+  /* Do not reclaim the symbols of the rule whose action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
   YY_STACK_PRINT (yyss, yyssp);
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-		  yystos[*yyssp], yyvsp, arg);
+                  yystos[*yyssp], yyvsp, arg);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
@@ -2173,14 +2009,9 @@ yyreturn:
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
 #endif
-  /* Make sure YYID is used.  */
-  return YYID (yyresult);
+  return yyresult;
 }
-
-
-
-/* Line 1675 of yacc.c  */
-#line 437 "dds.yy"
+#line 437 "dds.yy" /* yacc.c:1906  */
 
 
 /* 
@@ -2263,4 +2094,3 @@ void add_entry(DDS &table, stack<BaseType *> **ctor, BaseType **current, Part pa
     *current = 0;
 }
 
-
diff --git a/dds.tab.hh b/dds.tab.hh
index 7541b15..f7178f8 100644
--- a/dds.tab.hh
+++ b/dds.tab.hh
@@ -1,21 +1,19 @@
+/* A Bison parser, made by GNU Bison 3.0.1.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* Bison interface for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
 
-/* 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 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 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/>.  */
 
@@ -28,14 +26,21 @@
    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.  */
 
+#ifndef YY_DDS_DDS_TAB_HH_INCLUDED
+# define YY_DDS_DDS_TAB_HH_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int ddsdebug;
+#endif
 /* "%code requires" blocks.  */
-
-/* Line 1676 of yacc.c  */
-#line 47 "dds.yy"
+#line 47 "dds.yy" /* yacc.c:1909  */
 
 
 #include "config_dap.h"
@@ -81,58 +86,51 @@ using namespace libdap;
 extern int dds_line_num;	/* defined in dds.lex */
 
 
+#line 90 "dds.tab.hh" /* yacc.c:1909  */
 
-
-/* Line 1676 of yacc.c  */
-#line 88 "dds.tab.hh"
-
-/* Tokens.  */
+/* Token type.  */
 #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
-   };
+  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
 
-
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
 {
-
-/* Line 1676 of yacc.c  */
-#line 131 "dds.yy"
+#line 131 "dds.yy" /* yacc.c:1909  */
 
     bool boolean;
     char word[ID_MAX];
 
-
-
-/* Line 1676 of yacc.c  */
-#line 130 "dds.tab.hh"
-} YYSTYPE;
+#line 126 "dds.tab.hh" /* yacc.c:1909  */
+};
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
+
 extern YYSTYPE ddslval;
 
+int ddsparse (parser_arg *arg);
 
+#endif /* !YY_DDS_DDS_TAB_HH_INCLUDED  */
diff --git a/dods-datatypes-config.h.in b/dods-datatypes-config.h.in
index 9aa5b60..aea7a2b 100644
--- a/dods-datatypes-config.h.in
+++ b/dods-datatypes-config.h.in
@@ -54,5 +54,8 @@ typedef DINT64 dods_int64;
 #undef DUINT64
 typedef DUINT64 dods_uint64;
 
+/* Enums in DAP4 are 64-bit signed integers */
+typedef DINT64 dods_enum;
+
 #endif /* __DODS_DATATYPES__ */
 
diff --git a/dods-datatypes-static.h b/dods-datatypes-static.h
index ab5dce7..5cba1f6 100644
--- a/dods-datatypes-static.h
+++ b/dods-datatypes-static.h
@@ -1,19 +1,5 @@
-/* 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
+    This header is used when the compile-time definitions won't work.
 */
 
 #ifndef __DODS_DATATYPES__
@@ -24,12 +10,6 @@
 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;
@@ -51,6 +31,8 @@ typedef int64_t dods_int64;
 
 typedef uint64_t dods_uint64;
 
+typedef int64_t dods_enum;
+
 } // namespace libdap
 
 #endif /* __DODS_DATATYPES__ */
diff --git a/dods-datatypes.h b/dods-datatypes.h
index ab5dce7..5cba1f6 100644
--- a/dods-datatypes.h
+++ b/dods-datatypes.h
@@ -1,19 +1,5 @@
-/* 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
+    This header is used when the compile-time definitions won't work.
 */
 
 #ifndef __DODS_DATATYPES__
@@ -24,12 +10,6 @@
 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;
@@ -51,6 +31,8 @@ typedef int64_t dods_int64;
 
 typedef uint64_t dods_uint64;
 
+typedef int64_t dods_enum;
+
 } // namespace libdap
 
 #endif /* __DODS_DATATYPES__ */
diff --git a/dods-limits.h b/dods-limits.h
index d5fab95..f3ecd6c 100644
--- a/dods-limits.h
+++ b/dods-limits.h
@@ -81,6 +81,7 @@
 #define DODS_LLONG_MAX 0x7fffffffffffffffLL
 #define DODS_ULLONG_MAX 0xffffffffffffffffULL
 
+#define DODS_MAX_ARRAY_INDEX 0x1fffffffffffffffULL
 
 #define DODS_DBL_DIG 15 /* digits of precision of a "double" */
 #define DODS_DBL_MAX 1.7976931348623157E+308 /* max decimal value of a */
diff --git a/doxy.conf b/doxy.conf
index 3fb7a66..6042273 100644
--- a/doxy.conf
+++ b/doxy.conf
@@ -31,7 +31,7 @@ PROJECT_NAME           = libdap++
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = "Updated for version 3.12.0"
+PROJECT_NUMBER         = "Updated for version 3.14.0"
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
diff --git a/doxy_private.conf b/doxy_private.conf
index a7e4dfa..0fbfac6 100644
--- a/doxy_private.conf
+++ b/doxy_private.conf
@@ -12,7 +12,7 @@
 
 # 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 $
+# $Id$
 
 # $Log: doxy_private.conf,v $
 # Revision 1.3  2003/12/08 18:02:30  edavis
diff --git a/escaping.cc b/escaping.cc
index 0f55e90..bb1d87d 100644
--- a/escaping.cc
+++ b/escaping.cc
@@ -56,6 +56,8 @@
 //
 // -Todd
 
+#include "config.h"
+
 #include <ctype.h>
 
 #include <iomanip>
@@ -371,18 +373,18 @@ escattr(string s)
     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;
+    string::size_type ind = 0;
     while ((ind = s.find(ESC, ind)) != s.npos) {
         s.replace(ind, 1, DOUBLE_ESC);
         ind += DOUBLE_ESC.length();
     }
 
+    // escape non-printing characters with octal escape
+    ind = 0;
+    while ((ind = s.find_first_not_of(printable, ind)) != s.npos)
+        s.replace(ind, 1, ESC + octstring(s[ind]));
+
     // escape " with backslash
     ind = 0;
     while ((ind = s.find(QUOTE, ind)) != s.npos) {
diff --git a/expr.h b/expr.h
index bfdcf44..23591a7 100644
--- a/expr.h
+++ b/expr.h
@@ -39,24 +39,26 @@
 #include <string>
 #include <vector>
 
-#ifndef _basetype_h
-#include "BaseType.h"
-#endif
+#include <Type.h>
 
 namespace libdap
 {
 
+class BaseType;
+class DDS;
+class ConstraintEvaluator;
+
 // 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
+    Type type;   // Type is an enum defined in Type.h
     union {
         unsigned int ui;
         int i;
         double f;
-        string *s;
+        std::string *s;
     } v;
 } value;
 
@@ -67,18 +69,15 @@ typedef struct
 // evaluated (analogous to the ENVP in UNIX) and a pointer for the function's
 // return value. ARGC is the length of ARGV.
 
-/** @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);
+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);
+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.
diff --git a/getdap.cc b/getdap.cc
index ebef248..37fdf1a 100644
--- a/getdap.cc
+++ b/getdap.cc
@@ -64,56 +64,42 @@ 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;
+	cerr << "Usage: " << name << endl;
+	cerr << " [idaDxBzp vVkms][-c <expr>][-m <num>] <url> [<url> ...]" << endl;
+	cerr << " [M vVkms] <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 (DAP2) DDX object. Does not get data." << 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 and -d/r" << 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)
@@ -149,14 +135,13 @@ static void print_data(DDS & dds, bool print_rows = false)
 
 int main(int argc, char *argv[])
 {
-    GetOpt getopt(argc, argv, "idaDxXBVvkc:m:zshM?Hp:t");
+    GetOpt getopt(argc, argv, "idaDxrXBVvkc: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;
@@ -188,9 +173,6 @@ int main(int argc, char *argv[])
         case 'x':
             get_ddx = true;
             break;
-        case 'X':
-            get_data_ddx = true;
-            break;
         case 'V':
             fprintf(stderr, "getdap version: %s\n", version);
             exit(0);
@@ -263,11 +245,11 @@ int main(int argc, char *argv[])
 
             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]);
+                    fprintf(stderr, "Assuming that the argument %s is a file that contains a response object; decoding.\n", argv[i]);
                 }
 
                 Response *r = 0;
+
                 BaseTypeFactory factory;
                 DataDDS dds(&factory);
 
@@ -444,32 +426,6 @@ int main(int argc, char *argv[])
                     }
                 }
             }
-
-            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
diff --git a/getdap4.cc b/getdap4.cc
new file mode 100644
index 0000000..295e310
--- /dev/null
+++ b/getdap4.cc
@@ -0,0 +1,401 @@
+
+// -*- 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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"
+
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#include <cstring>
+#include <string>
+#include <sstream>
+
+#include "GetOpt.h"
+
+#include "DMR.h"
+#include "XMLWriter.h"
+#include "D4BaseTypeFactory.h"
+#include "D4Group.h"
+#include "D4Sequence.h"
+#include "D4Connect.h"
+#include "StdinResponse.h"
+#include "HTTPConnect.h"
+#include "RCReader.h"
+
+using namespace std;
+using namespace libdap ;
+
+const char *version = CVER " (" DVR " DAP/" DAP_PROTOCOL_VERSION ")";
+#if 0
+extern int libdap::dods_keep_temps;     // defined in HTTPResponse.h
+extern int libdap::www_trace;
+#endif
+static void usage(const string &name)
+{
+	cerr << "Usage: " << name << endl;
+	cerr << " [dD vVikmzstM][-c <expr>][-m <num>] <url> [<url> ...] | <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 << "        d: For each URL, get the (DAP4) DMR object. Does not get data." << endl;
+	cerr << "        D: For each URL, get the DAP4 Data response." << endl;
+	cerr << endl;
+	cerr << "        v: Verbose output." << endl;
+	cerr << "        V: Version of this client; see 'i' for server version." << endl;
+	cerr << "        i: For each URL, get the server version." << 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 << "        t: Trace www accesses." << endl;
+	cerr << "        M: Assume data read from a file has no MIME headers; use only with files" << endl;
+	cerr << endl;
+	cerr << "        c: <expr> is a constraint expression. Used with -d/D" << endl;
+	cerr << "           NB: You can use a `?' for the CE also." << endl;
+}
+
+#if 1
+// Used for raw http access/transfer
+bool read_data(FILE * fp)
+{
+    if (!fp) {
+        fprintf(stderr, "getdap4: 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;
+}
+#endif
+
+static void read_response_from_file(D4Connect *url, DMR &dmr, Response &r, bool mime_headers, bool get_dap4_data, bool get_dmr)
+{
+    if (mime_headers) {
+    	if (get_dap4_data)
+    		url->read_data(dmr, r);
+    	else if (get_dmr)
+    		url->read_dmr(dmr, r);
+    	else
+    		throw Error("Only supports Data or DMR responses");
+    }
+    else {
+    	if (get_dap4_data)
+    		url->read_data_no_mime(dmr, r);
+    	else if (get_dmr)
+    		url->read_dmr_no_mime(dmr, r);
+    	else
+    		throw Error("Only supports Data or DMR responses");
+    }
+}
+
+static void print_data(DMR &dmr, bool print_rows = false)
+{
+    cout << "The data:" << endl;
+
+    D4Group *g = dmr.root();
+    for (Constructor::Vars_iter i = g->var_begin(), e = g->var_end(); i != e; i++) {
+        if (print_rows && (*i)->type() == dods_sequence_c)
+            dynamic_cast < D4Sequence * >(*i)->print_val_by_rows(cout);
+        else
+            (*i)->print_val(cout);
+    }
+
+    cout << endl << flush;
+}
+
+int main(int argc, char *argv[])
+{
+    GetOpt getopt(argc, argv, "[dDvVikrm:Mzstc:]");
+    int option_char;
+
+    bool get_dmr = false;
+    bool get_dap4_data = 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;
+    bool report_errors = false;
+    int times = 1;
+    int dap_client_major = 4;
+    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_dmr = true;
+            break;
+        case 'D':
+            get_dap4_data = true;
+            break;
+        case 'v':
+            verbose = true;
+            break;
+        case 'V':
+        	cerr << "getdap4 version: " << version << endl;
+            exit(0);
+        case 'i':
+            get_version = true;
+            break;
+#if 0
+        case 'k':
+            dods_keep_temps = 1;
+            break;              // keep_temp is in Connect.cc
+#endif
+        case 'r':
+        	report_errors = true;
+        	break;
+        case 'm':
+            multi = true;
+            times = atoi(getopt.optarg);
+            break;
+        case 'z':
+            accept_deflate = true;
+            break;
+        case 's':
+            print_rows = true;
+            break;
+        case 'M':
+            mime_headers = false;
+            break;
+#if 0
+        case 't':
+            www_trace = 1;
+            break;
+#endif
+        case 'c':
+            cexpr = true;
+            expr = getopt.optarg;
+            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)
+                cerr << "Fetching: " << argv[i] << endl;
+
+            string name = argv[i];
+            D4Connect *url = 0;
+
+            url = new D4Connect(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)
+                    cerr << "Assuming " << argv[i] << " is a file that contains a response object; decoding." << endl;
+
+                try {
+                    D4BaseTypeFactory factory;
+                    DMR dmr(&factory);
+
+                    if (strcmp(argv[i], "-") == 0) {
+                        StdinResponse r(cin);
+
+                        if (!r.get_cpp_stream())
+                            throw Error("Could not open standard input.");
+
+                        read_response_from_file(url, dmr, r, mime_headers, get_dap4_data, get_dmr);
+                    }
+                    else {
+                    	fstream f(argv[i], std::ios_base::in);
+                    	if (!f.is_open() || f.bad() || f.eof())
+                    		throw Error((string)"Could not open: " + argv[i]);
+
+                    	Response r(&f, 0);
+
+                        read_response_from_file(url, dmr, r, mime_headers, get_dap4_data, get_dmr);
+                    }
+
+                    if (verbose)
+                        cerr << "DAP version: " << url->get_protocol().c_str() << " Server version: "
+    						<< url->get_version().c_str() << endl;
+
+                    // Always write the DMR
+                    XMLWriter xml;
+                    dmr.print_dap4(xml);
+                    cout << xml.get_doc() << endl;
+
+                    if (get_dap4_data)
+                    	print_data(dmr, print_rows);
+                }
+                catch (Error & e) {
+                    cerr << "Error: " << e.get_error_message() << endl;
+                    delete url; url = 0;
+                }
+            }
+            else if (get_dmr) {
+                for (int j = 0; j < times; ++j) {
+                    D4BaseTypeFactory factory;
+                    DMR dmr(&factory);
+                    try {
+                        url->request_dmr(dmr, expr);
+
+                        if (verbose) {
+                            cout << "DAP version: " << url->get_protocol() << ", Server version: " << url->get_version() << endl;
+                            cout << "DMR:" << endl;
+                        }
+
+                        XMLWriter xml;
+                        dmr.print_dap4(xml);
+                        cout << xml.get_doc() << endl;
+                    }
+                    catch (Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        if (report_errors)
+                        	return EXIT_FAILURE;
+                        continue;       // Goto the next URL or exit the loop.
+                    }
+                }
+            }
+            else if (get_dap4_data) {
+                 for (int j = 0; j < times; ++j) {
+                     D4BaseTypeFactory factory;
+                     DMR dmr(&factory);
+                     try {
+                         url->request_dap4_data(dmr, expr);
+
+                         if (verbose) {
+                             cout << "DAP version: " << url->get_protocol() << ", Server version: " << url->get_version() << endl;
+                             cout << "DMR:" << endl;
+                         }
+
+                         XMLWriter xml;
+                         dmr.print_dap4(xml);
+                         cout << xml.get_doc() << endl;
+
+                         print_data(dmr, print_rows);
+                    }
+                     catch (Error & e) {
+                         cerr << e.get_error_message() << endl;
+                         continue;       // Goto the next URL or exit the loop.
+                     }
+                 }
+            }
+            else {
+                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 {
+                        HTTPResponse *r = http.fetch_url(url_string);
+                        if (verbose) {
+                        	vector<string> *headers = r->get_headers();
+                        	copy(headers->begin(), headers->end(), ostream_iterator<string>(cout, "\n"));
+                        }
+                        if (!read_data(r->get_stream())) {
+                            continue;
+                        }
+                        delete r;
+                        r = 0;
+                    }
+                    catch (Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        continue;
+                    }
+                }
+            }
+
+#if 0
+            else if (get_version) {
+                fprintf(stderr, "DAP version: %s, Server version: %s\n",
+                        url->request_protocol().c_str(),
+                        url->get_version().c_str());
+            }
+#endif
+
+            delete url;  url = 0;
+        }
+    }
+    catch (Error &e) {
+        cerr << "Error: " << e.get_error_message() << endl;
+        cerr << "exiting" << endl;
+        return 1;
+    }
+    catch (exception &e) {
+        cerr << "C++ library exception: " << e.what() << endl;
+        cerr << "exiting" << endl;
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/getdap4.man1 b/getdap4.man1
new file mode 100644
index 0000000..343c4d7
--- /dev/null
+++ b/getdap4.man1
@@ -0,0 +1,99 @@
+.\" getdap.man
+.\" 
+.\"  Created on: Oct 28, 2013
+.\"      Author: jimg
+.\" 
+.\" Process this file with
+.\" groff -man -Tascii getdap4.1
+.\"
+.TH GETDAP4 1 "October 2013" Linux "User Manuals"
+.SH NAME
+getdap4 \- test driver for the libdap library DAP4 protocol
+.SH SYNOPSIS
+.B getdap4 [dD vVikmzst] [-c 
+.I expr
+.B ] [-m 
+.I num
+.B ]
+.I url
+.B ...
+
+.B getdap4 [-VvksM]
+.I file
+.B ...
+.SH DESCRIPTION
+.B getdap4
+A command line interface for DAP4, the follow-on to DAP2.
+While getdap can be used to access DAP2 response objects 
+and process those responses with the libdap client-side
+software, getdap4 fills the same role for DAP4.
+
+In the first form of the command, dereference the URL and
+perform the requested operations. This includes routing
+the returned information through the DAP processing
+library (parsing the returned objects, et c.). If neither
+of d or D are used with a URL, then the DAP library
+routines are NOT used and the URLs contents are dumped
+to standard output.
+
+In the second form of the command, assume the files are
+DAP4 Data objects (stored in files or read from pipes)
+and process them as if -D were given. In this case the
+information must contain valid MIME header in order
+to be processed or -M should be used.
+.SH OPTIONS
+.IP -i 
+For each URL, get the server version.
+.IP -d
+For each URL, get the the DAP4 DMR response.
+.IP -D
+For each URL, get the the DAP4 Data response.
+.IP -v
+Verbose output.
+.IP -V
+Version of this client; see 'i' for server version.
+.IP "-c expr" 
+.I expr
+is a constraint expression. Used with -D/X.
+You can use a `?' for the CE also.
+.IP -k
+Keep temporary files created by libdap.
+.IP "-m num"
+Request the same URL 
+.I num
+times
+.IP -z
+Ask the server to compress data.
+.IP -s
+Print Sequences using numbered rows.
+.IP -M
+Assume data read from a file has no MIME headers
+(the default is to assume the headers are present).
+.
+.SH FILES
+.I ~/.dodsrc
+.RS
+The 
+.I .dodsrc
+file contains various parameters that affect the runtime behavior for DAP clients.
+See
+.BR dodsrc (5)
+for further details.
+.RE
+.SH ENVIRONMENT
+.IP DODS_CONF
+Specifies an alternate file or directory for the 
+.I .dodsrc
+file.
+.SH DIAGNOSTICS
+Various self-explanatory messages may be issued on stderr.
+
+.SH BUGS
+The command name should have been chosen more carefully
+to reflect its purpose.
+
+The dodsrc man page needs to be written.
+.SH AUTHOR
+James Gallagher <jgallagher at opendap.org>
+.SH "SEE ALSO"
+.BR dodsrc (5)
diff --git a/gl/Makefile.am b/gl/Makefile.am
index 51046af..ded217a 100644
--- a/gl/Makefile.am
+++ b/gl/Makefile.am
@@ -1,6 +1,6 @@
 ## DO NOT EDIT! GENERATED AUTOMATICALLY!
 ## Process this file with automake to produce Makefile.in.
-# Copyright (C) 2002-2012 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
 #
 # 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
@@ -23,7 +23,7 @@
 # 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 --no-conditional-dependencies --libtool --macro-prefix=gl byteswap regex
 
-AUTOMAKE_OPTIONS = 1.5 gnits
+AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects
 
 SUBDIRS =
 noinst_HEADERS =
@@ -51,6 +51,7 @@ EXTRA_libgnu_la_SOURCES =
 libgnu_la_LDFLAGS = $(AM_LDFLAGS)
 libgnu_la_LDFLAGS += -no-undefined
 libgnu_la_LDFLAGS += $(LTLIBINTL)
+libgnu_la_LDFLAGS += $(LTLIBTHREAD)
 
 ## begin gnulib module alloca-opt
 
@@ -110,7 +111,7 @@ EXTRA_DIST += byteswap.in.h
 ## begin gnulib module configmake
 
 # Listed in the same order as the GNU makefile conventions, and
-# provided by autoconf 2.59c+.
+# provided by autoconf 2.59c+ or 2.70.
 # The Automake-defined pkg* macros are appended, in the order
 # listed in the Automake 1.10a+ documentation.
 configmake.h: Makefile
@@ -126,6 +127,7 @@ configmake.h: Makefile
 	  echo '#define SYSCONFDIR "$(sysconfdir)"'; \
 	  echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \
 	  echo '#define LOCALSTATEDIR "$(localstatedir)"'; \
+	  echo '#define RUNSTATEDIR "$(runstatedir)"'; \
 	  echo '#define INCLUDEDIR "$(includedir)"'; \
 	  echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \
 	  echo '#define DOCDIR "$(docdir)"'; \
@@ -157,6 +159,13 @@ libgnu_la_SOURCES += gettext.h
 
 ## end   gnulib module gettext-h
 
+## begin gnulib module havelib
+
+
+EXTRA_DIST += $(top_srcdir)/conf/config.rpath
+
+## end   gnulib module havelib
+
 ## begin gnulib module langinfo
 
 BUILT_SOURCES += langinfo.h
@@ -308,6 +317,12 @@ EXTRA_libgnu_la_SOURCES += localeconv.c
 
 ## end   gnulib module localeconv
 
+## begin gnulib module lock
+
+libgnu_la_SOURCES += glthread/lock.h glthread/lock.c
+
+## end   gnulib module lock
+
 ## begin gnulib module malloc-gnu
 
 
@@ -593,6 +608,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -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_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \
 	      -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \
 	      -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \
 	      -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \
@@ -621,6 +637,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -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_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \
 	      -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \
 	      -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \
 	      -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \
@@ -634,6 +651,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
 	      -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \
 	      -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+	      -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \
 	      -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \
 	      -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
 	      -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \
@@ -655,15 +673,6 @@ EXTRA_DIST += stdlib.in.h
 
 ## end   gnulib module stdlib
 
-## begin gnulib module strcase
-
-
-EXTRA_DIST += strcasecmp.c strncasecmp.c
-
-EXTRA_libgnu_la_SOURCES += strcasecmp.c strncasecmp.c
-
-## end   gnulib module strcase
-
 ## begin gnulib module streq
 
 
@@ -671,37 +680,6 @@ EXTRA_DIST += streq.h
 
 ## end   gnulib module streq
 
-## begin gnulib module strings
-
-BUILT_SOURCES += strings.h
-
-# We need the following in order to create <strings.h> when the system
-# doesn't have one that works with the given compiler.
-strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
-	      -e 's|@''HAVE_STRINGS_H''@|$(HAVE_STRINGS_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_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \
-	      -e 's|@''GNULIB_FFS''@|$(GNULIB_FFS)|g' \
-	      -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \
-	      -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \
-	      -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|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)/strings.in.h; \
-	} > $@-t && \
-	mv $@-t $@
-MOSTLYCLEANFILES += strings.h strings.h-t
-
-EXTRA_DIST += strings.in.h
-
-## end   gnulib module strings
-
 ## begin gnulib module sys_types
 
 BUILT_SOURCES += sys/types.h
@@ -727,9 +705,18 @@ EXTRA_DIST += sys_types.in.h
 
 ## end   gnulib module sys_types
 
+## begin gnulib module threadlib
+
+libgnu_la_SOURCES += glthread/threadlib.c
+
+EXTRA_DIST += $(top_srcdir)/conf/config.rpath
+
+## end   gnulib module threadlib
+
 ## begin gnulib module unistd
 
 BUILT_SOURCES += unistd.h
+libgnu_la_SOURCES += unistd.c
 
 # We need the following in order to create an empty placeholder for
 # <unistd.h> when the system doesn't have one.
@@ -844,6 +831,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \
 	      -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \
 	      -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \
+	      -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \
 	      -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \
 	      -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \
 	      -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \
@@ -1017,6 +1005,7 @@ EXTRA_libgnu_la_SOURCES += wcrtomb.c
 ## begin gnulib module wctype-h
 
 BUILT_SOURCES += wctype.h
+libgnu_la_SOURCES += wctype-h.c
 
 # We need the following in order to create <wctype.h> when the system
 # doesn't have one that works with the given compiler.
diff --git a/gl/Makefile.in b/gl/Makefile.in
index a0a93e0..755940a 100644
--- a/gl/Makefile.in
+++ b/gl/Makefile.in
@@ -15,7 +15,7 @@
 
 @SET_MAKE@
 
-# Copyright (C) 2002-2012 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
 #
 # 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
@@ -83,19 +83,23 @@ 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/byteswap.m4 $(top_srcdir)/gl/m4/codeset.m4 \
 	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/eealloc.m4 \
 	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/extern-inline.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/lib-ld.m4 $(top_srcdir)/gl/m4/lib-link.m4 \
+	$(top_srcdir)/gl/m4/lib-prefix.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/locale_h.m4 \
-	$(top_srcdir)/gl/m4/localeconv.m4 \
+	$(top_srcdir)/gl/m4/localeconv.m4 $(top_srcdir)/gl/m4/lock.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/mbtowc.m4 \
@@ -104,17 +108,18 @@ am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
 	$(top_srcdir)/gl/m4/off_t.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/strcase.m4 \
-	$(top_srcdir)/gl/m4/strings_h.m4 \
+	$(top_srcdir)/gl/m4/stdlib_h.m4 \
 	$(top_srcdir)/gl/m4/sys_types_h.m4 \
+	$(top_srcdir)/gl/m4/threadlib.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/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/cppunit.m4 \
+	$(top_srcdir)/conf/gcov_valgrind.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) \
@@ -128,7 +133,9 @@ CONFIG_CLEAN_VPATH_FILES =
 LIBRARIES = $(noinst_LIBRARIES)
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 am__DEPENDENCIES_1 =
-am_libgnu_la_OBJECTS = localcharset.lo
+am__dirstamp = $(am__leading_dot)dirstamp
+am_libgnu_la_OBJECTS = localcharset.lo glthread/lock.lo \
+	glthread/threadlib.lo unistd.lo wctype-h.lo
 libgnu_la_OBJECTS = $(am_libgnu_la_OBJECTS)
 libgnu_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -247,7 +254,6 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
-EVAL = @EVAL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GLIBC21 = @GLIBC21@
@@ -268,7 +274,6 @@ GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
 GNULIB_FCHDIR = @GNULIB_FCHDIR@
 GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
 GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
-GNULIB_FFS = @GNULIB_FFS@
 GNULIB_FSYNC = @GNULIB_FSYNC@
 GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
 GNULIB_GETCWD = @GNULIB_GETCWD@
@@ -322,6 +327,7 @@ GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
 GNULIB_REALPATH = @GNULIB_REALPATH@
 GNULIB_RMDIR = @GNULIB_RMDIR@
 GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
 GNULIB_SETENV = @GNULIB_SETENV@
 GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
 GNULIB_SETLOCALE = @GNULIB_SETLOCALE@
@@ -394,7 +400,6 @@ HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
 HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
 HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
 HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
-HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
 HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
 HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
 HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
@@ -408,7 +413,6 @@ HAVE_FCHDIR = @HAVE_FCHDIR@
 HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
 HAVE_FDATASYNC = @HAVE_FDATASYNC@
 HAVE_FEATURES_H = @HAVE_FEATURES_H@
-HAVE_FFS = @HAVE_FFS@
 HAVE_FSYNC = @HAVE_FSYNC@
 HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
 HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
@@ -457,6 +461,7 @@ HAVE_READLINK = @HAVE_READLINK@
 HAVE_READLINKAT = @HAVE_READLINKAT@
 HAVE_REALPATH = @HAVE_REALPATH@
 HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
 HAVE_SETENV = @HAVE_SETENV@
 HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
 HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
@@ -464,8 +469,6 @@ 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_STRCASECMP = @HAVE_STRCASECMP@
-HAVE_STRINGS_H = @HAVE_STRINGS_H@
 HAVE_STRTOD = @HAVE_STRTOD@
 HAVE_STRTOLL = @HAVE_STRTOLL@
 HAVE_STRTOULL = @HAVE_STRTOULL@
@@ -482,6 +485,7 @@ HAVE_UNLINKAT = @HAVE_UNLINKAT@
 HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
 HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
 HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_VALGRIND = @HAVE_VALGRIND@
 HAVE_WCHAR_H = @HAVE_WCHAR_H@
 HAVE_WCHAR_T = @HAVE_WCHAR_T@
 HAVE_WCPCPY = @HAVE_WCPCPY@
@@ -536,8 +540,12 @@ LEXLIB = @LEXLIB@
 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
 LIBDAP_VERSION = @LIBDAP_VERSION@
 LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
 LIBS = @LIBS@
+LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -547,7 +555,10 @@ LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
 LOCALE_JA = @LOCALE_JA@
 LOCALE_ZH_CN = @LOCALE_ZH_CN@
 LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -556,7 +567,6 @@ NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_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_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
 NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_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@
@@ -566,7 +576,6 @@ NEXT_LOCALE_H = @NEXT_LOCALE_H@
 NEXT_STDDEF_H = @NEXT_STDDEF_H@
 NEXT_STDINT_H = @NEXT_STDINT_H@
 NEXT_STDLIB_H = @NEXT_STDLIB_H@
-NEXT_STRINGS_H = @NEXT_STRINGS_H@
 NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
 NEXT_UNISTD_H = @NEXT_UNISTD_H@
 NEXT_WCHAR_H = @NEXT_WCHAR_H@
@@ -606,6 +615,7 @@ REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
 REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
 REPLACE_GETCWD = @REPLACE_GETCWD@
 REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
 REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
 REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
 REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
@@ -629,6 +639,7 @@ REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
 REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
 REPLACE_NULL = @REPLACE_NULL@
 REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
 REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
 REPLACE_PUTENV = @REPLACE_PUTENV@
 REPLACE_PWRITE = @REPLACE_PWRITE@
@@ -734,6 +745,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -744,22 +756,23 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 xmlprivatelibs = @xmlprivatelibs@
 xmlprivatereq = @xmlprivatereq@
-AUTOMAKE_OPTIONS = 1.5 gnits
+AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects
 SUBDIRS = 
 noinst_HEADERS = 
 noinst_LIBRARIES = 
 noinst_LTLIBRARIES = libgnu.la
 EXTRA_DIST = m4/gnulib-cache.m4 alloca.in.h btowc.c byteswap.in.h \
-	langinfo.in.h config.charset ref-add.sin ref-del.sin \
-	locale.in.h localeconv.c malloc.c malloc.c mbrtowc.c mbsinit.c \
-	mbtowc-impl.h mbtowc.c nl_langinfo.c regcomp.c regex.c regex.h \
-	regex_internal.c regex_internal.h regexec.c \
+	$(top_srcdir)/conf/config.rpath langinfo.in.h config.charset \
+	ref-add.sin ref-del.sin locale.in.h localeconv.c malloc.c \
+	malloc.c mbrtowc.c mbsinit.c mbtowc-impl.h mbtowc.c \
+	nl_langinfo.c regcomp.c regex.c regex.h regex_internal.c \
+	regex_internal.h regexec.c \
 	$(top_srcdir)/conf/snippet/_Noreturn.h \
 	$(top_srcdir)/conf/snippet/arg-nonnull.h \
 	$(top_srcdir)/conf/snippet/c++defs.h \
 	$(top_srcdir)/conf/snippet/warn-on-use.h stdbool.in.h \
-	stddef.in.h stdint.in.h stdlib.in.h strcasecmp.c strncasecmp.c \
-	streq.h strings.in.h sys_types.in.h unistd.in.h verify.h \
+	stddef.in.h stdint.in.h stdlib.in.h streq.h sys_types.in.h \
+	$(top_srcdir)/conf/config.rpath unistd.in.h verify.h \
 	wchar.in.h wcrtomb.c wctype.in.h
 
 # The BUILT_SOURCES created by this Makefile snippet are not used via #include
@@ -773,16 +786,16 @@ EXTRA_DIST = m4/gnulib-cache.m4 alloca.in.h btowc.c byteswap.in.h \
 # 'all' defined above.
 BUILT_SOURCES = $(ALLOCA_H) $(BYTESWAP_H) configmake.h langinfo.h \
 	locale.h arg-nonnull.h c++defs.h warn-on-use.h $(STDBOOL_H) \
-	$(STDDEF_H) $(STDINT_H) stdlib.h strings.h sys/types.h \
-	unistd.h wchar.h wctype.h
+	$(STDDEF_H) $(STDINT_H) stdlib.h sys/types.h unistd.h wchar.h \
+	wctype.h
 SUFFIXES = .sed .sin
 MOSTLYCLEANFILES = core *.stackdump alloca.h alloca.h-t byteswap.h \
 	byteswap.h-t langinfo.h langinfo.h-t locale.h locale.h-t \
 	arg-nonnull.h arg-nonnull.h-t c++defs.h c++defs.h-t \
 	warn-on-use.h warn-on-use.h-t stdbool.h stdbool.h-t stddef.h \
-	stddef.h-t stdint.h stdint.h-t stdlib.h stdlib.h-t strings.h \
-	strings.h-t sys/types.h sys/types.h-t unistd.h unistd.h-t \
-	wchar.h wchar.h-t wctype.h wctype.h-t
+	stddef.h-t stdint.h stdint.h-t stdlib.h stdlib.h-t sys/types.h \
+	sys/types.h-t unistd.h unistd.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
@@ -790,14 +803,16 @@ DISTCLEANFILES =
 MAINTAINERCLEANFILES = 
 AM_CPPFLAGS = 
 AM_CFLAGS = 
-libgnu_la_SOURCES = gettext.h localcharset.h localcharset.c
+libgnu_la_SOURCES = gettext.h localcharset.h localcharset.c \
+	glthread/lock.h glthread/lock.c glthread/threadlib.c unistd.c \
+	wctype-h.c
 libgnu_la_LIBADD = $(gl_LTLIBOBJS)
 libgnu_la_DEPENDENCIES = $(gl_LTLIBOBJS)
 EXTRA_libgnu_la_SOURCES = btowc.c localeconv.c malloc.c malloc.c \
 	mbrtowc.c mbsinit.c mbtowc.c nl_langinfo.c regcomp.c regex.c \
-	regex_internal.c regexec.c strcasecmp.c strncasecmp.c \
-	wcrtomb.c
-libgnu_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(LTLIBINTL)
+	regex_internal.c regexec.c wcrtomb.c
+libgnu_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(LTLIBINTL) \
+	$(LTLIBTHREAD)
 charset_alias = $(DESTDIR)$(libdir)/charset.alias
 charset_tmp = $(DESTDIR)$(libdir)/charset.tmp
 
@@ -857,11 +872,25 @@ clean-noinstLTLIBRARIES:
 	  echo rm -f $${locs}; \
 	  rm -f $${locs}; \
 	}
+glthread/$(am__dirstamp):
+	@$(MKDIR_P) glthread
+	@: > glthread/$(am__dirstamp)
+glthread/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) glthread/$(DEPDIR)
+	@: > glthread/$(DEPDIR)/$(am__dirstamp)
+glthread/lock.lo: glthread/$(am__dirstamp) \
+	glthread/$(DEPDIR)/$(am__dirstamp)
+glthread/threadlib.lo: glthread/$(am__dirstamp) \
+	glthread/$(DEPDIR)/$(am__dirstamp)
 libgnu.la: $(libgnu_la_OBJECTS) $(libgnu_la_DEPENDENCIES) $(EXTRA_libgnu_la_DEPENDENCIES) 
 	$(libgnu_la_LINK)  $(libgnu_la_OBJECTS) $(libgnu_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
+	-rm -f glthread/lock.$(OBJEXT)
+	-rm -f glthread/lock.lo
+	-rm -f glthread/threadlib.$(OBJEXT)
+	-rm -f glthread/threadlib.lo
 
 distclean-compile:
 	-rm -f *.tab.c
@@ -878,27 +907,32 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/regex.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/regex_internal.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/regexec.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/strcasecmp.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/strncasecmp.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/unistd.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/wcrtomb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/wctype-h.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at glthread/$(DEPDIR)/lock.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at glthread/$(DEPDIR)/threadlib.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 am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+ at am__fastdepCC_FALSE@	$(COMPILE) -c -o $@ $<
 
 .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 am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_FALSE@	$(COMPILE) -c -o $@ `$(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 am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
@@ -908,6 +942,7 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
+	-rm -rf glthread/.libs glthread/_libs
 
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run 'make' without going through this Makefile.
@@ -1152,6 +1187,8 @@ 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)
+	-rm -f glthread/$(DEPDIR)/$(am__dirstamp)
+	-rm -f glthread/$(am__dirstamp)
 	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
 
 maintainer-clean-generic:
@@ -1165,7 +1202,7 @@ clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
 	clean-noinstLTLIBRARIES mostlyclean-am
 
 distclean: distclean-recursive
-	-rm -rf ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR) glthread/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -1211,7 +1248,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
-	-rm -rf ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR) glthread/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -1275,7 +1312,7 @@ uninstall-am: uninstall-local
 @GL_GENERATE_BYTESWAP_H_FALSE@	rm -f $@
 
 # Listed in the same order as the GNU makefile conventions, and
-# provided by autoconf 2.59c+.
+# provided by autoconf 2.59c+ or 2.70.
 # The Automake-defined pkg* macros are appended, in the order
 # listed in the Automake 1.10a+ documentation.
 configmake.h: Makefile
@@ -1291,6 +1328,7 @@ configmake.h: Makefile
 	  echo '#define SYSCONFDIR "$(sysconfdir)"'; \
 	  echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \
 	  echo '#define LOCALSTATEDIR "$(localstatedir)"'; \
+	  echo '#define RUNSTATEDIR "$(runstatedir)"'; \
 	  echo '#define INCLUDEDIR "$(includedir)"'; \
 	  echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \
 	  echo '#define DOCDIR "$(docdir)"'; \
@@ -1547,6 +1585,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -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_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \
 	      -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \
 	      -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \
 	      -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \
@@ -1575,6 +1614,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -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_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \
 	      -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \
 	      -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \
 	      -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \
@@ -1588,6 +1628,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
 	      -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \
 	      -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+	      -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \
 	      -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \
 	      -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
 	      -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \
@@ -1604,28 +1645,6 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	} > $@-t && \
 	mv $@-t $@
 
-# We need the following in order to create <strings.h> when the system
-# doesn't have one that works with the given compiler.
-strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
-	      -e 's|@''HAVE_STRINGS_H''@|$(HAVE_STRINGS_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_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \
-	      -e 's|@''GNULIB_FFS''@|$(GNULIB_FFS)|g' \
-	      -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \
-	      -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \
-	      -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|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)/strings.in.h; \
-	} > $@-t && \
-	mv $@-t $@
-
 # We need the following in order to create <sys/types.h> when the system
 # doesn't have one that works with the given compiler.
 sys/types.h: sys_types.in.h $(top_builddir)/config.status
@@ -1755,6 +1774,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \
 	      -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \
 	      -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \
+	      -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \
 	      -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \
 	      -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \
 	      -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \
diff --git a/gl/alloca.in.h b/gl/alloca.in.h
index b5aaa88..19aea41 100644
--- a/gl/alloca.in.h
+++ b/gl/alloca.in.h
@@ -1,6 +1,6 @@
 /* Memory allocation on the stack.
 
-   Copyright (C) 1995, 1999, 2001-2004, 2006-2012 Free Software Foundation,
+   Copyright (C) 1995, 1999, 2001-2004, 2006-2013 Free Software Foundation,
    Inc.
 
    This program is free software; you can redistribute it and/or modify it
@@ -44,6 +44,13 @@
 #  define alloca _alloca
 # elif defined __DECC && defined __VMS
 #  define alloca __ALLOCA
+# elif defined __TANDEM && defined _TNS_E_TARGET
+#  ifdef  __cplusplus
+extern "C"
+#  endif
+void *_alloca (unsigned short);
+#  pragma intrinsic (_alloca)
+#  define alloca _alloca
 # else
 #  include <stddef.h>
 #  ifdef  __cplusplus
diff --git a/gl/btowc.c b/gl/btowc.c
index 485e995..aca5742 100644
--- a/gl/btowc.c
+++ b/gl/btowc.c
@@ -1,5 +1,5 @@
 /* Convert unibyte character to wide character.
-   Copyright (C) 2008, 2010-2012 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2010-2013 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
diff --git a/gl/byteswap.in.h b/gl/byteswap.in.h
index a9baa68..6c7ab6d 100644
--- a/gl/byteswap.in.h
+++ b/gl/byteswap.in.h
@@ -1,5 +1,5 @@
 /* byteswap.h - Byte swapping
-   Copyright (C) 2005, 2007, 2009-2012 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2009-2013 Free Software Foundation, Inc.
    Written by Oskar Liljeblad <oskar at osk.mine.nu>, 2005.
 
    This program is free software: you can redistribute it and/or modify
diff --git a/gl/config.charset b/gl/config.charset
index 58ac759..f15f5bb 100755
--- a/gl/config.charset
+++ b/gl/config.charset
@@ -1,7 +1,7 @@
 #! /bin/sh
 # Output a system dependent table of character encoding aliases.
 #
-#   Copyright (C) 2000-2004, 2006-2012 Free Software Foundation, Inc.
+#   Copyright (C) 2000-2004, 2006-2013 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
diff --git a/gl/gettext.h b/gl/gettext.h
index c7d9740..2cc0e05 100644
--- a/gl/gettext.h
+++ b/gl/gettext.h
@@ -1,5 +1,5 @@
 /* Convenience header for conditional use of GNU <libintl.h>.
-   Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2012 Free Software
+   Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2013 Free Software
    Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
@@ -183,9 +183,12 @@ npgettext_aux (const char *domain,
 
 #include <string.h>
 
-#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
-  (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \
-   /* || __STDC_VERSION__ >= 199901L */ )
+#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \
+     /* || __STDC_VERSION__ >= 199901L */ )
+# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1
+#else
+# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0
+#endif
 
 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
 #include <stdlib.h>
diff --git a/gl/glthread/lock.c b/gl/glthread/lock.c
new file mode 100644
index 0000000..4c2702e
--- /dev/null
+++ b/gl/glthread/lock.c
@@ -0,0 +1,1057 @@
+/* Locking in multithreaded situations.
+   Copyright (C) 2005-2013 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, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno at clisp.org>, 2005.
+   Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
+   gthr-win32.h.  */
+
+#include <config.h>
+
+#include "glthread/lock.h"
+
+/* ========================================================================= */
+
+#if USE_POSIX_THREADS
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+# if HAVE_PTHREAD_RWLOCK
+
+#  if !defined PTHREAD_RWLOCK_INITIALIZER
+
+int
+glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
+{
+  int err;
+
+  err = pthread_rwlock_init (&lock->rwlock, NULL);
+  if (err != 0)
+    return err;
+  lock->initialized = 1;
+  return 0;
+}
+
+int
+glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)
+{
+  if (!lock->initialized)
+    {
+      int err;
+
+      err = pthread_mutex_lock (&lock->guard);
+      if (err != 0)
+        return err;
+      if (!lock->initialized)
+        {
+          err = glthread_rwlock_init_multithreaded (lock);
+          if (err != 0)
+            {
+              pthread_mutex_unlock (&lock->guard);
+              return err;
+            }
+        }
+      err = pthread_mutex_unlock (&lock->guard);
+      if (err != 0)
+        return err;
+    }
+  return pthread_rwlock_rdlock (&lock->rwlock);
+}
+
+int
+glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)
+{
+  if (!lock->initialized)
+    {
+      int err;
+
+      err = pthread_mutex_lock (&lock->guard);
+      if (err != 0)
+        return err;
+      if (!lock->initialized)
+        {
+          err = glthread_rwlock_init_multithreaded (lock);
+          if (err != 0)
+            {
+              pthread_mutex_unlock (&lock->guard);
+              return err;
+            }
+        }
+      err = pthread_mutex_unlock (&lock->guard);
+      if (err != 0)
+        return err;
+    }
+  return pthread_rwlock_wrlock (&lock->rwlock);
+}
+
+int
+glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)
+{
+  if (!lock->initialized)
+    return EINVAL;
+  return pthread_rwlock_unlock (&lock->rwlock);
+}
+
+int
+glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)
+{
+  int err;
+
+  if (!lock->initialized)
+    return EINVAL;
+  err = pthread_rwlock_destroy (&lock->rwlock);
+  if (err != 0)
+    return err;
+  lock->initialized = 0;
+  return 0;
+}
+
+#  endif
+
+# else
+
+int
+glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
+{
+  int err;
+
+  err = pthread_mutex_init (&lock->lock, NULL);
+  if (err != 0)
+    return err;
+  err = pthread_cond_init (&lock->waiting_readers, NULL);
+  if (err != 0)
+    return err;
+  err = pthread_cond_init (&lock->waiting_writers, NULL);
+  if (err != 0)
+    return err;
+  lock->waiting_writers_count = 0;
+  lock->runcount = 0;
+  return 0;
+}
+
+int
+glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)
+{
+  int err;
+
+  err = pthread_mutex_lock (&lock->lock);
+  if (err != 0)
+    return err;
+  /* Test whether only readers are currently running, and whether the runcount
+     field will not overflow.  */
+  /* POSIX says: "It is implementation-defined whether the calling thread
+     acquires the lock when a writer does not hold the lock and there are
+     writers blocked on the lock."  Let's say, no: give the writers a higher
+     priority.  */
+  while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0))
+    {
+      /* This thread has to wait for a while.  Enqueue it among the
+         waiting_readers.  */
+      err = pthread_cond_wait (&lock->waiting_readers, &lock->lock);
+      if (err != 0)
+        {
+          pthread_mutex_unlock (&lock->lock);
+          return err;
+        }
+    }
+  lock->runcount++;
+  return pthread_mutex_unlock (&lock->lock);
+}
+
+int
+glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)
+{
+  int err;
+
+  err = pthread_mutex_lock (&lock->lock);
+  if (err != 0)
+    return err;
+  /* Test whether no readers or writers are currently running.  */
+  while (!(lock->runcount == 0))
+    {
+      /* This thread has to wait for a while.  Enqueue it among the
+         waiting_writers.  */
+      lock->waiting_writers_count++;
+      err = pthread_cond_wait (&lock->waiting_writers, &lock->lock);
+      if (err != 0)
+        {
+          lock->waiting_writers_count--;
+          pthread_mutex_unlock (&lock->lock);
+          return err;
+        }
+      lock->waiting_writers_count--;
+    }
+  lock->runcount--; /* runcount becomes -1 */
+  return pthread_mutex_unlock (&lock->lock);
+}
+
+int
+glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)
+{
+  int err;
+
+  err = pthread_mutex_lock (&lock->lock);
+  if (err != 0)
+    return err;
+  if (lock->runcount < 0)
+    {
+      /* Drop a writer lock.  */
+      if (!(lock->runcount == -1))
+        {
+          pthread_mutex_unlock (&lock->lock);
+          return EINVAL;
+        }
+      lock->runcount = 0;
+    }
+  else
+    {
+      /* Drop a reader lock.  */
+      if (!(lock->runcount > 0))
+        {
+          pthread_mutex_unlock (&lock->lock);
+          return EINVAL;
+        }
+      lock->runcount--;
+    }
+  if (lock->runcount == 0)
+    {
+      /* POSIX recommends that "write locks shall take precedence over read
+         locks", to avoid "writer starvation".  */
+      if (lock->waiting_writers_count > 0)
+        {
+          /* Wake up one of the waiting writers.  */
+          err = pthread_cond_signal (&lock->waiting_writers);
+          if (err != 0)
+            {
+              pthread_mutex_unlock (&lock->lock);
+              return err;
+            }
+        }
+      else
+        {
+          /* Wake up all waiting readers.  */
+          err = pthread_cond_broadcast (&lock->waiting_readers);
+          if (err != 0)
+            {
+              pthread_mutex_unlock (&lock->lock);
+              return err;
+            }
+        }
+    }
+  return pthread_mutex_unlock (&lock->lock);
+}
+
+int
+glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)
+{
+  int err;
+
+  err = pthread_mutex_destroy (&lock->lock);
+  if (err != 0)
+    return err;
+  err = pthread_cond_destroy (&lock->waiting_readers);
+  if (err != 0)
+    return err;
+  err = pthread_cond_destroy (&lock->waiting_writers);
+  if (err != 0)
+    return err;
+  return 0;
+}
+
+# endif
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+# if HAVE_PTHREAD_MUTEX_RECURSIVE
+
+#  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+
+int
+glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
+{
+  pthread_mutexattr_t attributes;
+  int err;
+
+  err = pthread_mutexattr_init (&attributes);
+  if (err != 0)
+    return err;
+  err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
+  if (err != 0)
+    {
+      pthread_mutexattr_destroy (&attributes);
+      return err;
+    }
+  err = pthread_mutex_init (lock, &attributes);
+  if (err != 0)
+    {
+      pthread_mutexattr_destroy (&attributes);
+      return err;
+    }
+  err = pthread_mutexattr_destroy (&attributes);
+  if (err != 0)
+    return err;
+  return 0;
+}
+
+#  else
+
+int
+glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
+{
+  pthread_mutexattr_t attributes;
+  int err;
+
+  err = pthread_mutexattr_init (&attributes);
+  if (err != 0)
+    return err;
+  err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
+  if (err != 0)
+    {
+      pthread_mutexattr_destroy (&attributes);
+      return err;
+    }
+  err = pthread_mutex_init (&lock->recmutex, &attributes);
+  if (err != 0)
+    {
+      pthread_mutexattr_destroy (&attributes);
+      return err;
+    }
+  err = pthread_mutexattr_destroy (&attributes);
+  if (err != 0)
+    return err;
+  lock->initialized = 1;
+  return 0;
+}
+
+int
+glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
+{
+  if (!lock->initialized)
+    {
+      int err;
+
+      err = pthread_mutex_lock (&lock->guard);
+      if (err != 0)
+        return err;
+      if (!lock->initialized)
+        {
+          err = glthread_recursive_lock_init_multithreaded (lock);
+          if (err != 0)
+            {
+              pthread_mutex_unlock (&lock->guard);
+              return err;
+            }
+        }
+      err = pthread_mutex_unlock (&lock->guard);
+      if (err != 0)
+        return err;
+    }
+  return pthread_mutex_lock (&lock->recmutex);
+}
+
+int
+glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
+{
+  if (!lock->initialized)
+    return EINVAL;
+  return pthread_mutex_unlock (&lock->recmutex);
+}
+
+int
+glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
+{
+  int err;
+
+  if (!lock->initialized)
+    return EINVAL;
+  err = pthread_mutex_destroy (&lock->recmutex);
+  if (err != 0)
+    return err;
+  lock->initialized = 0;
+  return 0;
+}
+
+#  endif
+
+# else
+
+int
+glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
+{
+  int err;
+
+  err = pthread_mutex_init (&lock->mutex, NULL);
+  if (err != 0)
+    return err;
+  lock->owner = (pthread_t) 0;
+  lock->depth = 0;
+  return 0;
+}
+
+int
+glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
+{
+  pthread_t self = pthread_self ();
+  if (lock->owner != self)
+    {
+      int err;
+
+      err = pthread_mutex_lock (&lock->mutex);
+      if (err != 0)
+        return err;
+      lock->owner = self;
+    }
+  if (++(lock->depth) == 0) /* wraparound? */
+    {
+      lock->depth--;
+      return EAGAIN;
+    }
+  return 0;
+}
+
+int
+glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
+{
+  if (lock->owner != pthread_self ())
+    return EPERM;
+  if (lock->depth == 0)
+    return EINVAL;
+  if (--(lock->depth) == 0)
+    {
+      lock->owner = (pthread_t) 0;
+      return pthread_mutex_unlock (&lock->mutex);
+    }
+  else
+    return 0;
+}
+
+int
+glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
+{
+  if (lock->owner != (pthread_t) 0)
+    return EBUSY;
+  return pthread_mutex_destroy (&lock->mutex);
+}
+
+# endif
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT;
+
+int
+glthread_once_singlethreaded (pthread_once_t *once_control)
+{
+  /* We don't know whether pthread_once_t is an integer type, a floating-point
+     type, a pointer type, or a structure type.  */
+  char *firstbyte = (char *)once_control;
+  if (*firstbyte == *(const char *)&fresh_once)
+    {
+      /* First time use of once_control.  Invert the first byte.  */
+      *firstbyte = ~ *(const char *)&fresh_once;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_PTH_THREADS
+
+/* Use the GNU Pth threads library.  */
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+static void
+glthread_once_call (void *arg)
+{
+  void (**gl_once_temp_addr) (void) = (void (**) (void)) arg;
+  void (*initfunction) (void) = *gl_once_temp_addr;
+  initfunction ();
+}
+
+int
+glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void))
+{
+  void (*temp) (void) = initfunction;
+  return (!pth_once (once_control, glthread_once_call, &temp) ? errno : 0);
+}
+
+int
+glthread_once_singlethreaded (pth_once_t *once_control)
+{
+  /* We know that pth_once_t is an integer type.  */
+  if (*once_control == PTH_ONCE_INIT)
+    {
+      /* First time use of once_control.  Invert the marker.  */
+      *once_control = ~ PTH_ONCE_INIT;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_SOLARIS_THREADS
+
+/* Use the old Solaris threads library.  */
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+int
+glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
+{
+  int err;
+
+  err = mutex_init (&lock->mutex, USYNC_THREAD, NULL);
+  if (err != 0)
+    return err;
+  lock->owner = (thread_t) 0;
+  lock->depth = 0;
+  return 0;
+}
+
+int
+glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
+{
+  thread_t self = thr_self ();
+  if (lock->owner != self)
+    {
+      int err;
+
+      err = mutex_lock (&lock->mutex);
+      if (err != 0)
+        return err;
+      lock->owner = self;
+    }
+  if (++(lock->depth) == 0) /* wraparound? */
+    {
+      lock->depth--;
+      return EAGAIN;
+    }
+  return 0;
+}
+
+int
+glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
+{
+  if (lock->owner != thr_self ())
+    return EPERM;
+  if (lock->depth == 0)
+    return EINVAL;
+  if (--(lock->depth) == 0)
+    {
+      lock->owner = (thread_t) 0;
+      return mutex_unlock (&lock->mutex);
+    }
+  else
+    return 0;
+}
+
+int
+glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
+{
+  if (lock->owner != (thread_t) 0)
+    return EBUSY;
+  return mutex_destroy (&lock->mutex);
+}
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+int
+glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void))
+{
+  if (!once_control->inited)
+    {
+      int err;
+
+      /* Use the mutex to guarantee that if another thread is already calling
+         the initfunction, this thread waits until it's finished.  */
+      err = mutex_lock (&once_control->mutex);
+      if (err != 0)
+        return err;
+      if (!once_control->inited)
+        {
+          once_control->inited = 1;
+          initfunction ();
+        }
+      return mutex_unlock (&once_control->mutex);
+    }
+  else
+    return 0;
+}
+
+int
+glthread_once_singlethreaded (gl_once_t *once_control)
+{
+  /* We know that gl_once_t contains an integer type.  */
+  if (!once_control->inited)
+    {
+      /* First time use of once_control.  Invert the marker.  */
+      once_control->inited = ~ 0;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_WINDOWS_THREADS
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+void
+glthread_lock_init_func (gl_lock_t *lock)
+{
+  InitializeCriticalSection (&lock->lock);
+  lock->guard.done = 1;
+}
+
+int
+glthread_lock_lock_func (gl_lock_t *lock)
+{
+  if (!lock->guard.done)
+    {
+      if (InterlockedIncrement (&lock->guard.started) == 0)
+        /* This thread is the first one to need this lock.  Initialize it.  */
+        glthread_lock_init (lock);
+      else
+        /* Yield the CPU while waiting for another thread to finish
+           initializing this lock.  */
+        while (!lock->guard.done)
+          Sleep (0);
+    }
+  EnterCriticalSection (&lock->lock);
+  return 0;
+}
+
+int
+glthread_lock_unlock_func (gl_lock_t *lock)
+{
+  if (!lock->guard.done)
+    return EINVAL;
+  LeaveCriticalSection (&lock->lock);
+  return 0;
+}
+
+int
+glthread_lock_destroy_func (gl_lock_t *lock)
+{
+  if (!lock->guard.done)
+    return EINVAL;
+  DeleteCriticalSection (&lock->lock);
+  lock->guard.done = 0;
+  return 0;
+}
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+/* In this file, the waitqueues are implemented as circular arrays.  */
+#define gl_waitqueue_t gl_carray_waitqueue_t
+
+static void
+gl_waitqueue_init (gl_waitqueue_t *wq)
+{
+  wq->array = NULL;
+  wq->count = 0;
+  wq->alloc = 0;
+  wq->offset = 0;
+}
+
+/* Enqueues the current thread, represented by an event, in a wait queue.
+   Returns INVALID_HANDLE_VALUE if an allocation failure occurs.  */
+static HANDLE
+gl_waitqueue_add (gl_waitqueue_t *wq)
+{
+  HANDLE event;
+  unsigned int index;
+
+  if (wq->count == wq->alloc)
+    {
+      unsigned int new_alloc = 2 * wq->alloc + 1;
+      HANDLE *new_array =
+        (HANDLE *) realloc (wq->array, new_alloc * sizeof (HANDLE));
+      if (new_array == NULL)
+        /* No more memory.  */
+        return INVALID_HANDLE_VALUE;
+      /* Now is a good opportunity to rotate the array so that its contents
+         starts at offset 0.  */
+      if (wq->offset > 0)
+        {
+          unsigned int old_count = wq->count;
+          unsigned int old_alloc = wq->alloc;
+          unsigned int old_offset = wq->offset;
+          unsigned int i;
+          if (old_offset + old_count > old_alloc)
+            {
+              unsigned int limit = old_offset + old_count - old_alloc;
+              for (i = 0; i < limit; i++)
+                new_array[old_alloc + i] = new_array[i];
+            }
+          for (i = 0; i < old_count; i++)
+            new_array[i] = new_array[old_offset + i];
+          wq->offset = 0;
+        }
+      wq->array = new_array;
+      wq->alloc = new_alloc;
+    }
+  /* Whether the created event is a manual-reset one or an auto-reset one,
+     does not matter, since we will wait on it only once.  */
+  event = CreateEvent (NULL, TRUE, FALSE, NULL);
+  if (event == INVALID_HANDLE_VALUE)
+    /* No way to allocate an event.  */
+    return INVALID_HANDLE_VALUE;
+  index = wq->offset + wq->count;
+  if (index >= wq->alloc)
+    index -= wq->alloc;
+  wq->array[index] = event;
+  wq->count++;
+  return event;
+}
+
+/* Notifies the first thread from a wait queue and dequeues it.  */
+static void
+gl_waitqueue_notify_first (gl_waitqueue_t *wq)
+{
+  SetEvent (wq->array[wq->offset + 0]);
+  wq->offset++;
+  wq->count--;
+  if (wq->count == 0 || wq->offset == wq->alloc)
+    wq->offset = 0;
+}
+
+/* Notifies all threads from a wait queue and dequeues them all.  */
+static void
+gl_waitqueue_notify_all (gl_waitqueue_t *wq)
+{
+  unsigned int i;
+
+  for (i = 0; i < wq->count; i++)
+    {
+      unsigned int index = wq->offset + i;
+      if (index >= wq->alloc)
+        index -= wq->alloc;
+      SetEvent (wq->array[index]);
+    }
+  wq->count = 0;
+  wq->offset = 0;
+}
+
+void
+glthread_rwlock_init_func (gl_rwlock_t *lock)
+{
+  InitializeCriticalSection (&lock->lock);
+  gl_waitqueue_init (&lock->waiting_readers);
+  gl_waitqueue_init (&lock->waiting_writers);
+  lock->runcount = 0;
+  lock->guard.done = 1;
+}
+
+int
+glthread_rwlock_rdlock_func (gl_rwlock_t *lock)
+{
+  if (!lock->guard.done)
+    {
+      if (InterlockedIncrement (&lock->guard.started) == 0)
+        /* This thread is the first one to need this lock.  Initialize it.  */
+        glthread_rwlock_init (lock);
+      else
+        /* Yield the CPU while waiting for another thread to finish
+           initializing this lock.  */
+        while (!lock->guard.done)
+          Sleep (0);
+    }
+  EnterCriticalSection (&lock->lock);
+  /* Test whether only readers are currently running, and whether the runcount
+     field will not overflow.  */
+  if (!(lock->runcount + 1 > 0))
+    {
+      /* This thread has to wait for a while.  Enqueue it among the
+         waiting_readers.  */
+      HANDLE event = gl_waitqueue_add (&lock->waiting_readers);
+      if (event != INVALID_HANDLE_VALUE)
+        {
+          DWORD result;
+          LeaveCriticalSection (&lock->lock);
+          /* Wait until another thread signals this event.  */
+          result = WaitForSingleObject (event, INFINITE);
+          if (result == WAIT_FAILED || result == WAIT_TIMEOUT)
+            abort ();
+          CloseHandle (event);
+          /* The thread which signalled the event already did the bookkeeping:
+             removed us from the waiting_readers, incremented lock->runcount.  */
+          if (!(lock->runcount > 0))
+            abort ();
+          return 0;
+        }
+      else
+        {
+          /* Allocation failure.  Weird.  */
+          do
+            {
+              LeaveCriticalSection (&lock->lock);
+              Sleep (1);
+              EnterCriticalSection (&lock->lock);
+            }
+          while (!(lock->runcount + 1 > 0));
+        }
+    }
+  lock->runcount++;
+  LeaveCriticalSection (&lock->lock);
+  return 0;
+}
+
+int
+glthread_rwlock_wrlock_func (gl_rwlock_t *lock)
+{
+  if (!lock->guard.done)
+    {
+      if (InterlockedIncrement (&lock->guard.started) == 0)
+        /* This thread is the first one to need this lock.  Initialize it.  */
+        glthread_rwlock_init (lock);
+      else
+        /* Yield the CPU while waiting for another thread to finish
+           initializing this lock.  */
+        while (!lock->guard.done)
+          Sleep (0);
+    }
+  EnterCriticalSection (&lock->lock);
+  /* Test whether no readers or writers are currently running.  */
+  if (!(lock->runcount == 0))
+    {
+      /* This thread has to wait for a while.  Enqueue it among the
+         waiting_writers.  */
+      HANDLE event = gl_waitqueue_add (&lock->waiting_writers);
+      if (event != INVALID_HANDLE_VALUE)
+        {
+          DWORD result;
+          LeaveCriticalSection (&lock->lock);
+          /* Wait until another thread signals this event.  */
+          result = WaitForSingleObject (event, INFINITE);
+          if (result == WAIT_FAILED || result == WAIT_TIMEOUT)
+            abort ();
+          CloseHandle (event);
+          /* The thread which signalled the event already did the bookkeeping:
+             removed us from the waiting_writers, set lock->runcount = -1.  */
+          if (!(lock->runcount == -1))
+            abort ();
+          return 0;
+        }
+      else
+        {
+          /* Allocation failure.  Weird.  */
+          do
+            {
+              LeaveCriticalSection (&lock->lock);
+              Sleep (1);
+              EnterCriticalSection (&lock->lock);
+            }
+          while (!(lock->runcount == 0));
+        }
+    }
+  lock->runcount--; /* runcount becomes -1 */
+  LeaveCriticalSection (&lock->lock);
+  return 0;
+}
+
+int
+glthread_rwlock_unlock_func (gl_rwlock_t *lock)
+{
+  if (!lock->guard.done)
+    return EINVAL;
+  EnterCriticalSection (&lock->lock);
+  if (lock->runcount < 0)
+    {
+      /* Drop a writer lock.  */
+      if (!(lock->runcount == -1))
+        abort ();
+      lock->runcount = 0;
+    }
+  else
+    {
+      /* Drop a reader lock.  */
+      if (!(lock->runcount > 0))
+        {
+          LeaveCriticalSection (&lock->lock);
+          return EPERM;
+        }
+      lock->runcount--;
+    }
+  if (lock->runcount == 0)
+    {
+      /* POSIX recommends that "write locks shall take precedence over read
+         locks", to avoid "writer starvation".  */
+      if (lock->waiting_writers.count > 0)
+        {
+          /* Wake up one of the waiting writers.  */
+          lock->runcount--;
+          gl_waitqueue_notify_first (&lock->waiting_writers);
+        }
+      else
+        {
+          /* Wake up all waiting readers.  */
+          lock->runcount += lock->waiting_readers.count;
+          gl_waitqueue_notify_all (&lock->waiting_readers);
+        }
+    }
+  LeaveCriticalSection (&lock->lock);
+  return 0;
+}
+
+int
+glthread_rwlock_destroy_func (gl_rwlock_t *lock)
+{
+  if (!lock->guard.done)
+    return EINVAL;
+  if (lock->runcount != 0)
+    return EBUSY;
+  DeleteCriticalSection (&lock->lock);
+  if (lock->waiting_readers.array != NULL)
+    free (lock->waiting_readers.array);
+  if (lock->waiting_writers.array != NULL)
+    free (lock->waiting_writers.array);
+  lock->guard.done = 0;
+  return 0;
+}
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+void
+glthread_recursive_lock_init_func (gl_recursive_lock_t *lock)
+{
+  lock->owner = 0;
+  lock->depth = 0;
+  InitializeCriticalSection (&lock->lock);
+  lock->guard.done = 1;
+}
+
+int
+glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock)
+{
+  if (!lock->guard.done)
+    {
+      if (InterlockedIncrement (&lock->guard.started) == 0)
+        /* This thread is the first one to need this lock.  Initialize it.  */
+        glthread_recursive_lock_init (lock);
+      else
+        /* Yield the CPU while waiting for another thread to finish
+           initializing this lock.  */
+        while (!lock->guard.done)
+          Sleep (0);
+    }
+  {
+    DWORD self = GetCurrentThreadId ();
+    if (lock->owner != self)
+      {
+        EnterCriticalSection (&lock->lock);
+        lock->owner = self;
+      }
+    if (++(lock->depth) == 0) /* wraparound? */
+      {
+        lock->depth--;
+        return EAGAIN;
+      }
+  }
+  return 0;
+}
+
+int
+glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock)
+{
+  if (lock->owner != GetCurrentThreadId ())
+    return EPERM;
+  if (lock->depth == 0)
+    return EINVAL;
+  if (--(lock->depth) == 0)
+    {
+      lock->owner = 0;
+      LeaveCriticalSection (&lock->lock);
+    }
+  return 0;
+}
+
+int
+glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock)
+{
+  if (lock->owner != 0)
+    return EBUSY;
+  DeleteCriticalSection (&lock->lock);
+  lock->guard.done = 0;
+  return 0;
+}
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+void
+glthread_once_func (gl_once_t *once_control, void (*initfunction) (void))
+{
+  if (once_control->inited <= 0)
+    {
+      if (InterlockedIncrement (&once_control->started) == 0)
+        {
+          /* This thread is the first one to come to this once_control.  */
+          InitializeCriticalSection (&once_control->lock);
+          EnterCriticalSection (&once_control->lock);
+          once_control->inited = 0;
+          initfunction ();
+          once_control->inited = 1;
+          LeaveCriticalSection (&once_control->lock);
+        }
+      else
+        {
+          /* Undo last operation.  */
+          InterlockedDecrement (&once_control->started);
+          /* Some other thread has already started the initialization.
+             Yield the CPU while waiting for the other thread to finish
+             initializing and taking the lock.  */
+          while (once_control->inited < 0)
+            Sleep (0);
+          if (once_control->inited <= 0)
+            {
+              /* Take the lock.  This blocks until the other thread has
+                 finished calling the initfunction.  */
+              EnterCriticalSection (&once_control->lock);
+              LeaveCriticalSection (&once_control->lock);
+              if (!(once_control->inited > 0))
+                abort ();
+            }
+        }
+    }
+}
+
+#endif
+
+/* ========================================================================= */
diff --git a/gl/glthread/lock.h b/gl/glthread/lock.h
new file mode 100644
index 0000000..4e75e38
--- /dev/null
+++ b/gl/glthread/lock.h
@@ -0,0 +1,927 @@
+/* Locking in multithreaded situations.
+   Copyright (C) 2005-2013 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, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno at clisp.org>, 2005.
+   Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
+   gthr-win32.h.  */
+
+/* This file contains locking primitives for use with a given thread library.
+   It does not contain primitives for creating threads or for other
+   synchronization primitives.
+
+   Normal (non-recursive) locks:
+     Type:                gl_lock_t
+     Declaration:         gl_lock_define(extern, name)
+     Initializer:         gl_lock_define_initialized(, name)
+     Initialization:      gl_lock_init (name);
+     Taking the lock:     gl_lock_lock (name);
+     Releasing the lock:  gl_lock_unlock (name);
+     De-initialization:   gl_lock_destroy (name);
+   Equivalent functions with control of error handling:
+     Initialization:      err = glthread_lock_init (&name);
+     Taking the lock:     err = glthread_lock_lock (&name);
+     Releasing the lock:  err = glthread_lock_unlock (&name);
+     De-initialization:   err = glthread_lock_destroy (&name);
+
+   Read-Write (non-recursive) locks:
+     Type:                gl_rwlock_t
+     Declaration:         gl_rwlock_define(extern, name)
+     Initializer:         gl_rwlock_define_initialized(, name)
+     Initialization:      gl_rwlock_init (name);
+     Taking the lock:     gl_rwlock_rdlock (name);
+                          gl_rwlock_wrlock (name);
+     Releasing the lock:  gl_rwlock_unlock (name);
+     De-initialization:   gl_rwlock_destroy (name);
+   Equivalent functions with control of error handling:
+     Initialization:      err = glthread_rwlock_init (&name);
+     Taking the lock:     err = glthread_rwlock_rdlock (&name);
+                          err = glthread_rwlock_wrlock (&name);
+     Releasing the lock:  err = glthread_rwlock_unlock (&name);
+     De-initialization:   err = glthread_rwlock_destroy (&name);
+
+   Recursive locks:
+     Type:                gl_recursive_lock_t
+     Declaration:         gl_recursive_lock_define(extern, name)
+     Initializer:         gl_recursive_lock_define_initialized(, name)
+     Initialization:      gl_recursive_lock_init (name);
+     Taking the lock:     gl_recursive_lock_lock (name);
+     Releasing the lock:  gl_recursive_lock_unlock (name);
+     De-initialization:   gl_recursive_lock_destroy (name);
+   Equivalent functions with control of error handling:
+     Initialization:      err = glthread_recursive_lock_init (&name);
+     Taking the lock:     err = glthread_recursive_lock_lock (&name);
+     Releasing the lock:  err = glthread_recursive_lock_unlock (&name);
+     De-initialization:   err = glthread_recursive_lock_destroy (&name);
+
+  Once-only execution:
+     Type:                gl_once_t
+     Initializer:         gl_once_define(extern, name)
+     Execution:           gl_once (name, initfunction);
+   Equivalent functions with control of error handling:
+     Execution:           err = glthread_once (&name, initfunction);
+*/
+
+
+#ifndef _LOCK_H
+#define _LOCK_H
+
+#include <errno.h>
+#include <stdlib.h>
+
+/* ========================================================================= */
+
+#if USE_POSIX_THREADS
+
+/* Use the POSIX threads library.  */
+
+# include <pthread.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# if PTHREAD_IN_USE_DETECTION_HARD
+
+/* The pthread_in_use() detection needs to be done at runtime.  */
+#  define pthread_in_use() \
+     glthread_in_use ()
+extern int glthread_in_use (void);
+
+# endif
+
+# if USE_POSIX_THREADS_WEAK
+
+/* Use weak references to the POSIX threads library.  */
+
+/* Weak references avoid dragging in external libraries if the other parts
+   of the program don't use them.  Here we use them, because we don't want
+   every program that uses libintl to depend on libpthread.  This assumes
+   that libpthread would not be loaded after libintl; i.e. if libintl is
+   loaded first, by an executable that does not depend on libpthread, and
+   then a module is dynamically loaded that depends on libpthread, libintl
+   will not be multithread-safe.  */
+
+/* The way to test at runtime whether libpthread is present is to test
+   whether a function pointer's value, such as &pthread_mutex_init, is
+   non-NULL.  However, some versions of GCC have a bug through which, in
+   PIC mode, &foo != NULL always evaluates to true if there is a direct
+   call to foo(...) in the same function.  To avoid this, we test the
+   address of a function in libpthread that we don't use.  */
+
+#  pragma weak pthread_mutex_init
+#  pragma weak pthread_mutex_lock
+#  pragma weak pthread_mutex_unlock
+#  pragma weak pthread_mutex_destroy
+#  pragma weak pthread_rwlock_init
+#  pragma weak pthread_rwlock_rdlock
+#  pragma weak pthread_rwlock_wrlock
+#  pragma weak pthread_rwlock_unlock
+#  pragma weak pthread_rwlock_destroy
+#  pragma weak pthread_once
+#  pragma weak pthread_cond_init
+#  pragma weak pthread_cond_wait
+#  pragma weak pthread_cond_signal
+#  pragma weak pthread_cond_broadcast
+#  pragma weak pthread_cond_destroy
+#  pragma weak pthread_mutexattr_init
+#  pragma weak pthread_mutexattr_settype
+#  pragma weak pthread_mutexattr_destroy
+#  ifndef pthread_self
+#   pragma weak pthread_self
+#  endif
+
+#  if !PTHREAD_IN_USE_DETECTION_HARD
+#   pragma weak pthread_cancel
+#   define pthread_in_use() (pthread_cancel != NULL)
+#  endif
+
+# else
+
+#  if !PTHREAD_IN_USE_DETECTION_HARD
+#   define pthread_in_use() 1
+#  endif
+
+# endif
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+typedef pthread_mutex_t gl_lock_t;
+# define gl_lock_define(STORAGECLASS, NAME) \
+    STORAGECLASS pthread_mutex_t NAME;
+# define gl_lock_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;
+# define gl_lock_initializer \
+    PTHREAD_MUTEX_INITIALIZER
+# define glthread_lock_init(LOCK) \
+    (pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0)
+# define glthread_lock_lock(LOCK) \
+    (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
+# define glthread_lock_unlock(LOCK) \
+    (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
+# define glthread_lock_destroy(LOCK) \
+    (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+# if HAVE_PTHREAD_RWLOCK
+
+#  ifdef PTHREAD_RWLOCK_INITIALIZER
+
+typedef pthread_rwlock_t gl_rwlock_t;
+#   define gl_rwlock_define(STORAGECLASS, NAME) \
+      STORAGECLASS pthread_rwlock_t NAME;
+#   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
+      STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
+#   define gl_rwlock_initializer \
+      PTHREAD_RWLOCK_INITIALIZER
+#   define glthread_rwlock_init(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0)
+#   define glthread_rwlock_rdlock(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0)
+#   define glthread_rwlock_wrlock(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0)
+#   define glthread_rwlock_unlock(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0)
+#   define glthread_rwlock_destroy(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0)
+
+#  else
+
+typedef struct
+        {
+          int initialized;
+          pthread_mutex_t guard;   /* protects the initialization */
+          pthread_rwlock_t rwlock; /* read-write lock */
+        }
+        gl_rwlock_t;
+#   define gl_rwlock_define(STORAGECLASS, NAME) \
+      STORAGECLASS gl_rwlock_t NAME;
+#   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
+      STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
+#   define gl_rwlock_initializer \
+      { 0, PTHREAD_MUTEX_INITIALIZER }
+#   define glthread_rwlock_init(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
+#   define glthread_rwlock_rdlock(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
+#   define glthread_rwlock_wrlock(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
+#   define glthread_rwlock_unlock(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
+#   define glthread_rwlock_destroy(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
+
+#  endif
+
+# else
+
+typedef struct
+        {
+          pthread_mutex_t lock; /* protects the remaining fields */
+          pthread_cond_t waiting_readers; /* waiting readers */
+          pthread_cond_t waiting_writers; /* waiting writers */
+          unsigned int waiting_writers_count; /* number of waiting writers */
+          int runcount; /* number of readers running, or -1 when a writer runs */
+        }
+        gl_rwlock_t;
+# define gl_rwlock_define(STORAGECLASS, NAME) \
+    STORAGECLASS gl_rwlock_t NAME;
+# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
+# define gl_rwlock_initializer \
+    { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
+# define glthread_rwlock_init(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
+# define glthread_rwlock_rdlock(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
+# define glthread_rwlock_wrlock(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
+# define glthread_rwlock_unlock(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
+# define glthread_rwlock_destroy(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
+
+# endif
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+# if HAVE_PTHREAD_MUTEX_RECURSIVE
+
+#  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+
+typedef pthread_mutex_t gl_recursive_lock_t;
+#   define gl_recursive_lock_define(STORAGECLASS, NAME) \
+      STORAGECLASS pthread_mutex_t NAME;
+#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
+      STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer;
+#   ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+#    define gl_recursive_lock_initializer \
+       PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+#   else
+#    define gl_recursive_lock_initializer \
+       PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+#   endif
+#   define glthread_recursive_lock_init(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
+#   define glthread_recursive_lock_lock(LOCK) \
+      (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
+#   define glthread_recursive_lock_unlock(LOCK) \
+      (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
+#   define glthread_recursive_lock_destroy(LOCK) \
+      (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
+extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
+
+#  else
+
+typedef struct
+        {
+          pthread_mutex_t recmutex; /* recursive mutex */
+          pthread_mutex_t guard;    /* protects the initialization */
+          int initialized;
+        }
+        gl_recursive_lock_t;
+#   define gl_recursive_lock_define(STORAGECLASS, NAME) \
+      STORAGECLASS gl_recursive_lock_t NAME;
+#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
+      STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
+#   define gl_recursive_lock_initializer \
+      { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }
+#   define glthread_recursive_lock_init(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
+#   define glthread_recursive_lock_lock(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
+#   define glthread_recursive_lock_unlock(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
+#   define glthread_recursive_lock_destroy(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
+
+#  endif
+
+# else
+
+/* Old versions of POSIX threads on Solaris did not have recursive locks.
+   We have to implement them ourselves.  */
+
+typedef struct
+        {
+          pthread_mutex_t mutex;
+          pthread_t owner;
+          unsigned long depth;
+        }
+        gl_recursive_lock_t;
+#  define gl_recursive_lock_define(STORAGECLASS, NAME) \
+     STORAGECLASS gl_recursive_lock_t NAME;
+#  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
+     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
+#  define gl_recursive_lock_initializer \
+     { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }
+#  define glthread_recursive_lock_init(LOCK) \
+     (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
+#  define glthread_recursive_lock_lock(LOCK) \
+     (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
+#  define glthread_recursive_lock_unlock(LOCK) \
+     (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
+#  define glthread_recursive_lock_destroy(LOCK) \
+     (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
+
+# endif
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+typedef pthread_once_t gl_once_t;
+# define gl_once_define(STORAGECLASS, NAME) \
+    STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (pthread_in_use ()                                                         \
+     ? pthread_once (ONCE_CONTROL, INITFUNCTION)                               \
+     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
+extern int glthread_once_singlethreaded (pthread_once_t *once_control);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_PTH_THREADS
+
+/* Use the GNU Pth threads library.  */
+
+# include <pth.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# if USE_PTH_THREADS_WEAK
+
+/* Use weak references to the GNU Pth threads library.  */
+
+#  pragma weak pth_mutex_init
+#  pragma weak pth_mutex_acquire
+#  pragma weak pth_mutex_release
+#  pragma weak pth_rwlock_init
+#  pragma weak pth_rwlock_acquire
+#  pragma weak pth_rwlock_release
+#  pragma weak pth_once
+
+#  pragma weak pth_cancel
+#  define pth_in_use() (pth_cancel != NULL)
+
+# else
+
+#  define pth_in_use() 1
+
+# endif
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+typedef pth_mutex_t gl_lock_t;
+# define gl_lock_define(STORAGECLASS, NAME) \
+    STORAGECLASS pth_mutex_t NAME;
+# define gl_lock_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS pth_mutex_t NAME = gl_lock_initializer;
+# define gl_lock_initializer \
+    PTH_MUTEX_INIT
+# define glthread_lock_init(LOCK) \
+    (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
+# define glthread_lock_lock(LOCK) \
+    (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
+# define glthread_lock_unlock(LOCK) \
+    (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
+# define glthread_lock_destroy(LOCK) \
+    ((void)(LOCK), 0)
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+typedef pth_rwlock_t gl_rwlock_t;
+#  define gl_rwlock_define(STORAGECLASS, NAME) \
+     STORAGECLASS pth_rwlock_t NAME;
+#  define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
+     STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer;
+#  define gl_rwlock_initializer \
+     PTH_RWLOCK_INIT
+#  define glthread_rwlock_init(LOCK) \
+     (pth_in_use () && !pth_rwlock_init (LOCK) ? errno : 0)
+#  define glthread_rwlock_rdlock(LOCK) \
+     (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RD, 0, NULL) ? errno : 0)
+#  define glthread_rwlock_wrlock(LOCK) \
+     (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RW, 0, NULL) ? errno : 0)
+#  define glthread_rwlock_unlock(LOCK) \
+     (pth_in_use () && !pth_rwlock_release (LOCK) ? errno : 0)
+#  define glthread_rwlock_destroy(LOCK) \
+     ((void)(LOCK), 0)
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+/* In Pth, mutexes are recursive by default.  */
+typedef pth_mutex_t gl_recursive_lock_t;
+#  define gl_recursive_lock_define(STORAGECLASS, NAME) \
+     STORAGECLASS pth_mutex_t NAME;
+#  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
+     STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer;
+#  define gl_recursive_lock_initializer \
+     PTH_MUTEX_INIT
+#  define glthread_recursive_lock_init(LOCK) \
+     (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
+#  define glthread_recursive_lock_lock(LOCK) \
+     (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
+#  define glthread_recursive_lock_unlock(LOCK) \
+     (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
+#  define glthread_recursive_lock_destroy(LOCK) \
+     ((void)(LOCK), 0)
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+typedef pth_once_t gl_once_t;
+# define gl_once_define(STORAGECLASS, NAME) \
+    STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT;
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (pth_in_use ()                                                             \
+     ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)                \
+     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
+extern int glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void));
+extern int glthread_once_singlethreaded (pth_once_t *once_control);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_SOLARIS_THREADS
+
+/* Use the old Solaris threads library.  */
+
+# include <thread.h>
+# include <synch.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# if USE_SOLARIS_THREADS_WEAK
+
+/* Use weak references to the old Solaris threads library.  */
+
+#  pragma weak mutex_init
+#  pragma weak mutex_lock
+#  pragma weak mutex_unlock
+#  pragma weak mutex_destroy
+#  pragma weak rwlock_init
+#  pragma weak rw_rdlock
+#  pragma weak rw_wrlock
+#  pragma weak rw_unlock
+#  pragma weak rwlock_destroy
+#  pragma weak thr_self
+
+#  pragma weak thr_suspend
+#  define thread_in_use() (thr_suspend != NULL)
+
+# else
+
+#  define thread_in_use() 1
+
+# endif
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+typedef mutex_t gl_lock_t;
+# define gl_lock_define(STORAGECLASS, NAME) \
+    STORAGECLASS mutex_t NAME;
+# define gl_lock_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS mutex_t NAME = gl_lock_initializer;
+# define gl_lock_initializer \
+    DEFAULTMUTEX
+# define glthread_lock_init(LOCK) \
+    (thread_in_use () ? mutex_init (LOCK, USYNC_THREAD, NULL) : 0)
+# define glthread_lock_lock(LOCK) \
+    (thread_in_use () ? mutex_lock (LOCK) : 0)
+# define glthread_lock_unlock(LOCK) \
+    (thread_in_use () ? mutex_unlock (LOCK) : 0)
+# define glthread_lock_destroy(LOCK) \
+    (thread_in_use () ? mutex_destroy (LOCK) : 0)
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+typedef rwlock_t gl_rwlock_t;
+# define gl_rwlock_define(STORAGECLASS, NAME) \
+    STORAGECLASS rwlock_t NAME;
+# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS rwlock_t NAME = gl_rwlock_initializer;
+# define gl_rwlock_initializer \
+    DEFAULTRWLOCK
+# define glthread_rwlock_init(LOCK) \
+    (thread_in_use () ? rwlock_init (LOCK, USYNC_THREAD, NULL) : 0)
+# define glthread_rwlock_rdlock(LOCK) \
+    (thread_in_use () ? rw_rdlock (LOCK) : 0)
+# define glthread_rwlock_wrlock(LOCK) \
+    (thread_in_use () ? rw_wrlock (LOCK) : 0)
+# define glthread_rwlock_unlock(LOCK) \
+    (thread_in_use () ? rw_unlock (LOCK) : 0)
+# define glthread_rwlock_destroy(LOCK) \
+    (thread_in_use () ? rwlock_destroy (LOCK) : 0)
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+/* Old Solaris threads did not have recursive locks.
+   We have to implement them ourselves.  */
+
+typedef struct
+        {
+          mutex_t mutex;
+          thread_t owner;
+          unsigned long depth;
+        }
+        gl_recursive_lock_t;
+# define gl_recursive_lock_define(STORAGECLASS, NAME) \
+    STORAGECLASS gl_recursive_lock_t NAME;
+# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
+# define gl_recursive_lock_initializer \
+    { DEFAULTMUTEX, (thread_t) 0, 0 }
+# define glthread_recursive_lock_init(LOCK) \
+    (thread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
+# define glthread_recursive_lock_lock(LOCK) \
+    (thread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
+# define glthread_recursive_lock_unlock(LOCK) \
+    (thread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
+# define glthread_recursive_lock_destroy(LOCK) \
+    (thread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+typedef struct
+        {
+          volatile int inited;
+          mutex_t mutex;
+        }
+        gl_once_t;
+# define gl_once_define(STORAGECLASS, NAME) \
+    STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX };
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (thread_in_use ()                                                          \
+     ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)                \
+     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
+extern int glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void));
+extern int glthread_once_singlethreaded (gl_once_t *once_control);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_WINDOWS_THREADS
+
+# define WIN32_LEAN_AND_MEAN  /* avoid including junk */
+# include <windows.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/* We can use CRITICAL_SECTION directly, rather than the native Windows Event,
+   Mutex, Semaphore types, because
+     - we need only to synchronize inside a single process (address space),
+       not inter-process locking,
+     - we don't need to support trylock operations.  (TryEnterCriticalSection
+       does not work on Windows 95/98/ME.  Packages that need trylock usually
+       define their own mutex type.)  */
+
+/* There is no way to statically initialize a CRITICAL_SECTION.  It needs
+   to be done lazily, once only.  For this we need spinlocks.  */
+
+typedef struct { volatile int done; volatile long started; } gl_spinlock_t;
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+typedef struct
+        {
+          gl_spinlock_t guard; /* protects the initialization */
+          CRITICAL_SECTION lock;
+        }
+        gl_lock_t;
+# define gl_lock_define(STORAGECLASS, NAME) \
+    STORAGECLASS gl_lock_t NAME;
+# define gl_lock_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
+# define gl_lock_initializer \
+    { { 0, -1 } }
+# define glthread_lock_init(LOCK) \
+    (glthread_lock_init_func (LOCK), 0)
+# define glthread_lock_lock(LOCK) \
+    glthread_lock_lock_func (LOCK)
+# define glthread_lock_unlock(LOCK) \
+    glthread_lock_unlock_func (LOCK)
+# define glthread_lock_destroy(LOCK) \
+    glthread_lock_destroy_func (LOCK)
+extern void glthread_lock_init_func (gl_lock_t *lock);
+extern int glthread_lock_lock_func (gl_lock_t *lock);
+extern int glthread_lock_unlock_func (gl_lock_t *lock);
+extern int glthread_lock_destroy_func (gl_lock_t *lock);
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+/* It is impossible to implement read-write locks using plain locks, without
+   introducing an extra thread dedicated to managing read-write locks.
+   Therefore here we need to use the low-level Event type.  */
+
+typedef struct
+        {
+          HANDLE *array; /* array of waiting threads, each represented by an event */
+          unsigned int count; /* number of waiting threads */
+          unsigned int alloc; /* length of allocated array */
+          unsigned int offset; /* index of first waiting thread in array */
+        }
+        gl_carray_waitqueue_t;
+typedef struct
+        {
+          gl_spinlock_t guard; /* protects the initialization */
+          CRITICAL_SECTION lock; /* protects the remaining fields */
+          gl_carray_waitqueue_t waiting_readers; /* waiting readers */
+          gl_carray_waitqueue_t waiting_writers; /* waiting writers */
+          int runcount; /* number of readers running, or -1 when a writer runs */
+        }
+        gl_rwlock_t;
+# define gl_rwlock_define(STORAGECLASS, NAME) \
+    STORAGECLASS gl_rwlock_t NAME;
+# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
+# define gl_rwlock_initializer \
+    { { 0, -1 } }
+# define glthread_rwlock_init(LOCK) \
+    (glthread_rwlock_init_func (LOCK), 0)
+# define glthread_rwlock_rdlock(LOCK) \
+    glthread_rwlock_rdlock_func (LOCK)
+# define glthread_rwlock_wrlock(LOCK) \
+    glthread_rwlock_wrlock_func (LOCK)
+# define glthread_rwlock_unlock(LOCK) \
+    glthread_rwlock_unlock_func (LOCK)
+# define glthread_rwlock_destroy(LOCK) \
+    glthread_rwlock_destroy_func (LOCK)
+extern void glthread_rwlock_init_func (gl_rwlock_t *lock);
+extern int glthread_rwlock_rdlock_func (gl_rwlock_t *lock);
+extern int glthread_rwlock_wrlock_func (gl_rwlock_t *lock);
+extern int glthread_rwlock_unlock_func (gl_rwlock_t *lock);
+extern int glthread_rwlock_destroy_func (gl_rwlock_t *lock);
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+/* The native Windows documentation says that CRITICAL_SECTION already
+   implements a recursive lock.  But we need not rely on it: It's easy to
+   implement a recursive lock without this assumption.  */
+
+typedef struct
+        {
+          gl_spinlock_t guard; /* protects the initialization */
+          DWORD owner;
+          unsigned long depth;
+          CRITICAL_SECTION lock;
+        }
+        gl_recursive_lock_t;
+# define gl_recursive_lock_define(STORAGECLASS, NAME) \
+    STORAGECLASS gl_recursive_lock_t NAME;
+# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
+# define gl_recursive_lock_initializer \
+    { { 0, -1 }, 0, 0 }
+# define glthread_recursive_lock_init(LOCK) \
+    (glthread_recursive_lock_init_func (LOCK), 0)
+# define glthread_recursive_lock_lock(LOCK) \
+    glthread_recursive_lock_lock_func (LOCK)
+# define glthread_recursive_lock_unlock(LOCK) \
+    glthread_recursive_lock_unlock_func (LOCK)
+# define glthread_recursive_lock_destroy(LOCK) \
+    glthread_recursive_lock_destroy_func (LOCK)
+extern void glthread_recursive_lock_init_func (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock);
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+typedef struct
+        {
+          volatile int inited;
+          volatile long started;
+          CRITICAL_SECTION lock;
+        }
+        gl_once_t;
+# define gl_once_define(STORAGECLASS, NAME) \
+    STORAGECLASS gl_once_t NAME = { -1, -1 };
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (glthread_once_func (ONCE_CONTROL, INITFUNCTION), 0)
+extern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (void));
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS)
+
+/* Provide dummy implementation if threads are not supported.  */
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+typedef int gl_lock_t;
+# define gl_lock_define(STORAGECLASS, NAME)
+# define gl_lock_define_initialized(STORAGECLASS, NAME)
+# define glthread_lock_init(NAME) 0
+# define glthread_lock_lock(NAME) 0
+# define glthread_lock_unlock(NAME) 0
+# define glthread_lock_destroy(NAME) 0
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+typedef int gl_rwlock_t;
+# define gl_rwlock_define(STORAGECLASS, NAME)
+# define gl_rwlock_define_initialized(STORAGECLASS, NAME)
+# define glthread_rwlock_init(NAME) 0
+# define glthread_rwlock_rdlock(NAME) 0
+# define glthread_rwlock_wrlock(NAME) 0
+# define glthread_rwlock_unlock(NAME) 0
+# define glthread_rwlock_destroy(NAME) 0
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+typedef int gl_recursive_lock_t;
+# define gl_recursive_lock_define(STORAGECLASS, NAME)
+# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)
+# define glthread_recursive_lock_init(NAME) 0
+# define glthread_recursive_lock_lock(NAME) 0
+# define glthread_recursive_lock_unlock(NAME) 0
+# define glthread_recursive_lock_destroy(NAME) 0
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+typedef int gl_once_t;
+# define gl_once_define(STORAGECLASS, NAME) \
+    STORAGECLASS gl_once_t NAME = 0;
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0)
+
+#endif
+
+/* ========================================================================= */
+
+/* Macros with built-in error handling.  */
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+#define gl_lock_init(NAME) \
+   do                                  \
+     {                                 \
+       if (glthread_lock_init (&NAME)) \
+         abort ();                     \
+     }                                 \
+   while (0)
+#define gl_lock_lock(NAME) \
+   do                                  \
+     {                                 \
+       if (glthread_lock_lock (&NAME)) \
+         abort ();                     \
+     }                                 \
+   while (0)
+#define gl_lock_unlock(NAME) \
+   do                                    \
+     {                                   \
+       if (glthread_lock_unlock (&NAME)) \
+         abort ();                       \
+     }                                   \
+   while (0)
+#define gl_lock_destroy(NAME) \
+   do                                     \
+     {                                    \
+       if (glthread_lock_destroy (&NAME)) \
+         abort ();                        \
+     }                                    \
+   while (0)
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+#define gl_rwlock_init(NAME) \
+   do                                    \
+     {                                   \
+       if (glthread_rwlock_init (&NAME)) \
+         abort ();                       \
+     }                                   \
+   while (0)
+#define gl_rwlock_rdlock(NAME) \
+   do                                      \
+     {                                     \
+       if (glthread_rwlock_rdlock (&NAME)) \
+         abort ();                         \
+     }                                     \
+   while (0)
+#define gl_rwlock_wrlock(NAME) \
+   do                                      \
+     {                                     \
+       if (glthread_rwlock_wrlock (&NAME)) \
+         abort ();                         \
+     }                                     \
+   while (0)
+#define gl_rwlock_unlock(NAME) \
+   do                                      \
+     {                                     \
+       if (glthread_rwlock_unlock (&NAME)) \
+         abort ();                         \
+     }                                     \
+   while (0)
+#define gl_rwlock_destroy(NAME) \
+   do                                       \
+     {                                      \
+       if (glthread_rwlock_destroy (&NAME)) \
+         abort ();                          \
+     }                                      \
+   while (0)
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+#define gl_recursive_lock_init(NAME) \
+   do                                            \
+     {                                           \
+       if (glthread_recursive_lock_init (&NAME)) \
+         abort ();                               \
+     }                                           \
+   while (0)
+#define gl_recursive_lock_lock(NAME) \
+   do                                            \
+     {                                           \
+       if (glthread_recursive_lock_lock (&NAME)) \
+         abort ();                               \
+     }                                           \
+   while (0)
+#define gl_recursive_lock_unlock(NAME) \
+   do                                              \
+     {                                             \
+       if (glthread_recursive_lock_unlock (&NAME)) \
+         abort ();                                 \
+     }                                             \
+   while (0)
+#define gl_recursive_lock_destroy(NAME) \
+   do                                               \
+     {                                              \
+       if (glthread_recursive_lock_destroy (&NAME)) \
+         abort ();                                  \
+     }                                              \
+   while (0)
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+#define gl_once(NAME, INITFUNCTION) \
+   do                                           \
+     {                                          \
+       if (glthread_once (&NAME, INITFUNCTION)) \
+         abort ();                              \
+     }                                          \
+   while (0)
+
+/* ========================================================================= */
+
+#endif /* _LOCK_H */
diff --git a/gl/glthread/threadlib.c b/gl/glthread/threadlib.c
new file mode 100644
index 0000000..9ec1789
--- /dev/null
+++ b/gl/glthread/threadlib.c
@@ -0,0 +1,73 @@
+/* Multithreading primitives.
+   Copyright (C) 2005-2013 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, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno at clisp.org>, 2005.  */
+
+#include <config.h>
+
+/* ========================================================================= */
+
+#if USE_POSIX_THREADS
+
+/* Use the POSIX threads library.  */
+
+# include <pthread.h>
+# include <stdlib.h>
+
+# if PTHREAD_IN_USE_DETECTION_HARD
+
+/* The function to be executed by a dummy thread.  */
+static void *
+dummy_thread_func (void *arg)
+{
+  return arg;
+}
+
+int
+glthread_in_use (void)
+{
+  static int tested;
+  static int result; /* 1: linked with -lpthread, 0: only with libc */
+
+  if (!tested)
+    {
+      pthread_t thread;
+
+      if (pthread_create (&thread, NULL, dummy_thread_func, NULL) != 0)
+        /* Thread creation failed.  */
+        result = 0;
+      else
+        {
+          /* Thread creation works.  */
+          void *retval;
+          if (pthread_join (thread, &retval) != 0)
+            abort ();
+          result = 1;
+        }
+      tested = 1;
+    }
+  return result;
+}
+
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+/* This declaration is solely to ensure that after preprocessing
+   this file is never empty.  */
+typedef int dummy;
diff --git a/gl/langinfo.in.h b/gl/langinfo.in.h
index 63b92fd..d60a980 100644
--- a/gl/langinfo.in.h
+++ b/gl/langinfo.in.h
@@ -1,5 +1,5 @@
 /* Substitute for and wrapper around <langinfo.h>.
-   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+   Copyright (C) 2009-2013 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
diff --git a/gl/localcharset.c b/gl/localcharset.c
index ce20310..054e7db 100644
--- a/gl/localcharset.c
+++ b/gl/localcharset.c
@@ -1,6 +1,6 @@
 /* Determine a canonical name for the current locale's character encoding.
 
-   Copyright (C) 2000-2006, 2008-2012 Free Software Foundation, Inc.
+   Copyright (C) 2000-2006, 2008-2013 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
@@ -65,6 +65,11 @@
 # include <os2.h>
 #endif
 
+/* For MB_CUR_MAX_L */
+#if defined DARWIN7
+# include <xlocale.h>
+#endif
+
 #if ENABLE_RELOCATABLE
 # include "relocatable.h"
 #else
@@ -542,5 +547,12 @@ locale_charset (void)
   if (codeset[0] == '\0')
     codeset = "ASCII";
 
+#ifdef DARWIN7
+  /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8"
+     (the default codeset) does not work when MB_CUR_MAX is 1.  */
+  if (strcmp (codeset, "UTF-8") == 0 && MB_CUR_MAX_L (uselocale (NULL)) <= 1)
+    codeset = "ASCII";
+#endif
+
   return codeset;
 }
diff --git a/gl/localcharset.h b/gl/localcharset.h
index c1882aa..ce3b7fb 100644
--- a/gl/localcharset.h
+++ b/gl/localcharset.h
@@ -1,5 +1,5 @@
 /* Determine a canonical name for the current locale's character encoding.
-   Copyright (C) 2000-2003, 2009-2012 Free Software Foundation, Inc.
+   Copyright (C) 2000-2003, 2009-2013 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
diff --git a/gl/locale.in.h b/gl/locale.in.h
index 89b6745..ca67816 100644
--- a/gl/locale.in.h
+++ b/gl/locale.in.h
@@ -1,5 +1,5 @@
 /* A POSIX <locale.h>.
-   Copyright (C) 2007-2012 Free Software Foundation, Inc.
+   Copyright (C) 2007-2013 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
@@ -14,16 +14,30 @@
    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/>.  */
 
-#ifndef _ at GUARD_PREFIX@_LOCALE_H
-
 #if __GNUC__ >= 3
 @PRAGMA_SYSTEM_HEADER@
 #endif
 @PRAGMA_COLUMNS@
 
+#ifdef _GL_ALREADY_INCLUDING_LOCALE_H
+
+/* Special invocation conventions to handle Solaris header files
+   (through Solaris 10) when combined with gettext's libintl.h.  */
+
+#@INCLUDE_NEXT@ @NEXT_LOCALE_H@
+
+#else
+/* Normal invocation convention.  */
+
+#ifndef _ at GUARD_PREFIX@_LOCALE_H
+
+#define _GL_ALREADY_INCLUDING_LOCALE_H
+
 /* The include_next requires a split double-inclusion guard.  */
 #@INCLUDE_NEXT@ @NEXT_LOCALE_H@
 
+#undef _GL_ALREADY_INCLUDING_LOCALE_H
+
 #ifndef _ at GUARD_PREFIX@_LOCALE_H
 #define _ at GUARD_PREFIX@_LOCALE_H
 
@@ -198,4 +212,5 @@ _GL_WARN_ON_USE (duplocale, "duplocale is buggy on some glibc systems - "
 #endif
 
 #endif /* _ at GUARD_PREFIX@_LOCALE_H */
+#endif /* ! _GL_ALREADY_INCLUDING_LOCALE_H */
 #endif /* _ at GUARD_PREFIX@_LOCALE_H */
diff --git a/gl/localeconv.c b/gl/localeconv.c
index c22860c..41396a0 100644
--- a/gl/localeconv.c
+++ b/gl/localeconv.c
@@ -1,5 +1,5 @@
 /* Query locale dependent information for formatting numbers.
-   Copyright (C) 2012 Free Software Foundation, Inc.
+   Copyright (C) 2012-2013 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
diff --git a/gl/m4/00gnulib.m4 b/gl/m4/00gnulib.m4
index d978cb8..d4ad759 100644
--- a/gl/m4/00gnulib.m4
+++ b/gl/m4/00gnulib.m4
@@ -1,5 +1,5 @@
 # 00gnulib.m4 serial 2
-dnl Copyright (C) 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-2013 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.
diff --git a/gl/m4/alloca.m4 b/gl/m4/alloca.m4
index 656924b..270abd0 100644
--- a/gl/m4/alloca.m4
+++ b/gl/m4/alloca.m4
@@ -1,5 +1,5 @@
 # alloca.m4 serial 14
-dnl Copyright (C) 2002-2004, 2006-2007, 2009-2012 Free Software Foundation,
+dnl Copyright (C) 2002-2004, 2006-2007, 2009-2013 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,
diff --git a/gl/m4/btowc.m4 b/gl/m4/btowc.m4
index e565321..978a06e 100644
--- a/gl/m4/btowc.m4
+++ b/gl/m4/btowc.m4
@@ -1,5 +1,5 @@
 # btowc.m4 serial 10
-dnl Copyright (C) 2008-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-2013 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.
diff --git a/gl/m4/byteswap.m4 b/gl/m4/byteswap.m4
index f3b7ec9..7566903 100644
--- a/gl/m4/byteswap.m4
+++ b/gl/m4/byteswap.m4
@@ -1,5 +1,5 @@
 # byteswap.m4 serial 4
-dnl Copyright (C) 2005, 2007, 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2005, 2007, 2009-2013 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.
diff --git a/gl/m4/codeset.m4 b/gl/m4/codeset.m4
index cf53d24..c2761be 100644
--- a/gl/m4/codeset.m4
+++ b/gl/m4/codeset.m4
@@ -1,5 +1,5 @@
 # codeset.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2000-2002, 2006, 2008-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2000-2002, 2006, 2008-2013 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.
diff --git a/gl/m4/configmake.m4 b/gl/m4/configmake.m4
index 8c82371..330f98d 100644
--- a/gl/m4/configmake.m4
+++ b/gl/m4/configmake.m4
@@ -1,5 +1,5 @@
-# configmake.m4 serial 1
-dnl Copyright (C) 2010-2012 Free Software Foundation, Inc.
+# configmake.m4 serial 2
+dnl Copyright (C) 2010-2013 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.
@@ -7,8 +7,9 @@ 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.).
+# autoconf 2.59 (datarootdir wasn't supported until 2.59c, and runstatedir
+# in 2.70) or automake 1.9.6 (pkglibexecdir wasn't supported until 1.10b,
+# and runstatedir in 1.14.1).
 AC_DEFUN([gl_CONFIGMAKE_PREP],
 [
   dnl Technically, datadir should default to datarootdir.  But if
@@ -43,6 +44,10 @@ AC_DEFUN([gl_CONFIGMAKE_PREP],
   if test "x$localedir" = x; then
     AC_SUBST([localedir], ['${datarootdir}/locale'])
   fi
+  dnl Added in autoconf 2.70
+  if test "x$runstatedir" = x; then
+    AC_SUBST([runstatedir], ['${localstatedir}/run'])
+  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.
diff --git a/gl/m4/eealloc.m4 b/gl/m4/eealloc.m4
new file mode 100644
index 0000000..c640ec1
--- /dev/null
+++ b/gl/m4/eealloc.m4
@@ -0,0 +1,31 @@
+# eealloc.m4 serial 3
+dnl Copyright (C) 2003, 2009-2013 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_EEALLOC],
+[
+  AC_REQUIRE([gl_EEMALLOC])
+  AC_REQUIRE([gl_EEREALLOC])
+])
+
+AC_DEFUN([gl_EEMALLOC],
+[
+  _AC_FUNC_MALLOC_IF(
+    [gl_cv_func_malloc_0_nonnull=1],
+    [gl_cv_func_malloc_0_nonnull=0])
+  AC_DEFINE_UNQUOTED([MALLOC_0_IS_NONNULL], [$gl_cv_func_malloc_0_nonnull],
+    [If malloc(0) is != NULL, define this to 1.  Otherwise define this
+     to 0.])
+])
+
+AC_DEFUN([gl_EEREALLOC],
+[
+  _AC_FUNC_REALLOC_IF(
+    [gl_cv_func_realloc_0_nonnull=1],
+    [gl_cv_func_realloc_0_nonnull=0])
+  AC_DEFINE_UNQUOTED([REALLOC_0_IS_NONNULL], [$gl_cv_func_realloc_0_nonnull],
+    [If realloc(NULL,0) is != NULL, define this to 1.  Otherwise define this
+     to 0.])
+])
diff --git a/gl/m4/extensions.m4 b/gl/m4/extensions.m4
index 6d17d8a..e30f122 100644
--- a/gl/m4/extensions.m4
+++ b/gl/m4/extensions.m4
@@ -1,14 +1,14 @@
-# serial 12  -*- Autoconf -*-
+# serial 13  -*- Autoconf -*-
 # Enable extensions on systems that normally disable them.
 
-# Copyright (C) 2003, 2006-2012 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2006-2013 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
+# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from git
 # Autoconf.  Perhaps we can remove this once we can assume Autoconf
-# 2.62 or later everywhere, but since CVS Autoconf mutates rapidly
+# 2.70 or later everywhere, but since Autoconf mutates rapidly
 # enough in this area it's likely we'll need to redefine
 # AC_USE_SYSTEM_EXTENSIONS for quite some time.
 
@@ -30,6 +30,7 @@
 # ------------------------
 # 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
@@ -38,8 +39,6 @@ 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],
@@ -50,24 +49,18 @@ AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
        except with this defined.])
     AC_DEFINE([_MINIX], [1],
       [Define to 1 if on MINIX.])
+    AC_DEFINE([_NETBSD_SOURCE], [1],
+      [Define to 1 to make NetBSD features available.  MINIX 3 needs this.])
   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__],
+dnl Use a different key than __EXTENSIONS__, as that name broke existing
+dnl configure.ac when using autoheader 2.62.
+  AH_VERBATIM([USE_SYSTEM_EXTENSIONS],
 [/* Enable extensions on AIX 3, Interix.  */
 #ifndef _ALL_SOURCE
 # undef _ALL_SOURCE
 #endif
-/* Enable general extensions on Mac OS X.  */
+/* Enable general extensions on OS X.  */
 #ifndef _DARWIN_C_SOURCE
 # undef _DARWIN_C_SOURCE
 #endif
@@ -83,6 +76,12 @@ AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
 #ifndef _TANDEM_SOURCE
 # undef _TANDEM_SOURCE
 #endif
+/* Enable X/Open extensions if necessary.  HP-UX 11.11 defines
+   mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of
+   whether compiling with -Ae or -D_HPUX_SOURCE=1.  */
+#ifndef _XOPEN_SOURCE
+# undef _XOPEN_SOURCE
+#endif
 /* Enable general extensions on Solaris.  */
 #ifndef __EXTENSIONS__
 # undef __EXTENSIONS__
@@ -103,6 +102,22 @@ AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
   AC_DEFINE([_GNU_SOURCE])
   AC_DEFINE([_POSIX_PTHREAD_SEMANTICS])
   AC_DEFINE([_TANDEM_SOURCE])
+  AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined],
+    [ac_cv_should_define__xopen_source],
+    [ac_cv_should_define__xopen_source=no
+     AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM([[
+          #include <wchar.h>
+          mbstate_t x;]])],
+       [],
+       [AC_COMPILE_IFELSE(
+          [AC_LANG_PROGRAM([[
+             #define _XOPEN_SOURCE 500
+             #include <wchar.h>
+             mbstate_t x;]])],
+          [ac_cv_should_define__xopen_source=yes])])])
+  test $ac_cv_should_define__xopen_source = yes &&
+    AC_DEFINE([_XOPEN_SOURCE], [500])
 ])# AC_USE_SYSTEM_EXTENSIONS
 
 # gl_USE_SYSTEM_EXTENSIONS
diff --git a/gl/m4/extern-inline.m4 b/gl/m4/extern-inline.m4
new file mode 100644
index 0000000..4862d60
--- /dev/null
+++ b/gl/m4/extern-inline.m4
@@ -0,0 +1,79 @@
+dnl 'extern inline' a la ISO C99.
+
+dnl Copyright 2012-2013 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_EXTERN_INLINE],
+[
+  AH_VERBATIM([extern_inline],
+[/* Please see the Gnulib manual for how to use these macros.
+
+   Suppress extern inline with HP-UX cc, as it appears to be broken; see
+   <http://lists.gnu.org/archive/html/bug-texinfo/2013-02/msg00030.html>.
+
+   Suppress extern inline with Sun C in standards-conformance mode, as it
+   mishandles inline functions that call each other.  E.g., for 'inline void f
+   (void) { } inline void g (void) { f (); }', c99 incorrectly complains
+   'reference to static identifier "f" in extern inline function'.
+   This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.
+
+   Suppress the use of extern inline on problematic Apple configurations, as
+   Libc at least through Libc-825.26 (2013-04-09) mishandles it; see, e.g.,
+   <http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html>.
+   Perhaps Apple will fix this some day.  */
+#if (defined __APPLE__ \
+     && ((! defined _DONT_USE_CTYPE_INLINE_ \
+          && (defined __GNUC__ || defined __cplusplus)) \
+         || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \
+             && defined __GNUC__ && ! defined __cplusplus)))
+# define _GL_EXTERN_INLINE_APPLE_BUG
+#endif
+#if ((__GNUC__ \
+      ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
+      : (199901L <= __STDC_VERSION__ \
+         && !defined __HP_cc \
+         && !(defined __SUNPRO_C && __STDC__))) \
+     && !defined _GL_EXTERN_INLINE_APPLE_BUG)
+# define _GL_INLINE inline
+# define _GL_EXTERN_INLINE extern inline
+# define _GL_EXTERN_INLINE_IN_USE
+#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \
+       && !defined _GL_EXTERN_INLINE_APPLE_BUG)
+# if __GNUC_GNU_INLINE__
+   /* __gnu_inline__ suppresses a GCC 4.2 diagnostic.  */
+#  define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))
+# else
+#  define _GL_INLINE extern inline
+# endif
+# define _GL_EXTERN_INLINE extern
+# define _GL_EXTERN_INLINE_IN_USE
+#else
+# define _GL_INLINE static _GL_UNUSED
+# define _GL_EXTERN_INLINE static _GL_UNUSED
+#endif
+
+#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__
+#  define _GL_INLINE_HEADER_CONST_PRAGMA
+# else
+#  define _GL_INLINE_HEADER_CONST_PRAGMA \
+     _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"")
+# endif
+  /* Suppress GCC's bogus "no previous prototype for 'FOO'"
+     and "no previous declaration for 'FOO'"  diagnostics,
+     when FOO is an inline function in the header; see
+     <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113>.  */
+# define _GL_INLINE_HEADER_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \
+    _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \
+    _GL_INLINE_HEADER_CONST_PRAGMA
+# define _GL_INLINE_HEADER_END \
+    _Pragma ("GCC diagnostic pop")
+#else
+# define _GL_INLINE_HEADER_BEGIN
+# define _GL_INLINE_HEADER_END
+#endif])
+])
diff --git a/gl/m4/fcntl-o.m4 b/gl/m4/fcntl-o.m4
index 9862741..87cc4bd 100644
--- a/gl/m4/fcntl-o.m4
+++ b/gl/m4/fcntl-o.m4
@@ -1,5 +1,5 @@
 # fcntl-o.m4 serial 4
-dnl Copyright (C) 2006, 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2006, 2009-2013 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.
@@ -50,7 +50,18 @@ AC_DEFUN([gl_FCNTL_O_FLAGS],
             #if HAVE_SYMLINK
             {
               static char const sym[] = "conftest.sym";
-              if (symlink (".", sym) != 0)
+              if (symlink ("/dev/null", sym) != 0)
+                result |= 2;
+              else
+                {
+                  int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0);
+                  if (fd >= 0)
+                    {
+                      close (fd);
+                      result |= 4;
+                    }
+                }
+              if (unlink (sym) != 0 || symlink (".", sym) != 0)
                 result |= 2;
               else
                 {
diff --git a/gl/m4/glibc21.m4 b/gl/m4/glibc21.m4
index c938fb1..613fb2a 100644
--- a/gl/m4/glibc21.m4
+++ b/gl/m4/glibc21.m4
@@ -1,5 +1,5 @@
 # glibc21.m4 serial 5
-dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2012 Free Software Foundation,
+dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2013 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,
diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4
index c7196a3..a95de77 100644
--- a/gl/m4/gnulib-cache.m4
+++ b/gl/m4/gnulib-cache.m4
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2012 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
 #
 # 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
@@ -47,4 +47,4 @@ gl_MAKEFILE_NAME([])
 gl_LIBTOOL
 gl_MACRO_PREFIX([gl])
 gl_PO_DOMAIN([])
-gl_WITNESS_C_DOMAIN([])
+gl_WITNESS_C_MACRO([])
diff --git a/gl/m4/gnulib-common.m4 b/gl/m4/gnulib-common.m4
index 15d2b2b..0ae5a9e 100644
--- a/gl/m4/gnulib-common.m4
+++ b/gl/m4/gnulib-common.m4
@@ -1,5 +1,5 @@
 # gnulib-common.m4 serial 33
-dnl Copyright (C) 2007-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-2013 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.
@@ -294,6 +294,8 @@ Amsterdam
 # 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.
+# AC_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness.
+m4_ifndef([AC_AUTOCONF_VERSION],[
 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],
@@ -304,13 +306,15 @@ m4_ifdef([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_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness.
+m4_ifndef([AC_AUTOCONF_VERSION],[
 AC_DEFUN([AC_C_RESTRICT],
 [AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict],
   [ac_cv_c_restrict=no
diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4
index ae09ed7..eba4a2d 100644
--- a/gl/m4/gnulib-comp.m4
+++ b/gl/m4/gnulib-comp.m4
@@ -1,5 +1,5 @@
 # DO NOT EDIT! GENERATED AUTOMATICALLY!
-# Copyright (C) 2002-2012 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
 #
 # 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
@@ -38,18 +38,22 @@ AC_DEFUN([gl_EARLY],
   m4_pattern_allow([^gl_LIBOBJS$])dnl a variable
   m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable
   AC_REQUIRE([gl_PROG_AR_RANLIB])
+  AC_REQUIRE([AM_PROG_CC_C_O])
   # Code from module alloca-opt:
   # Code from module btowc:
   # Code from module byteswap:
   # Code from module configmake:
   # Code from module extensions:
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  # Code from module extern-inline:
   # Code from module gettext-h:
+  # Code from module havelib:
   # Code from module include_next:
   # Code from module langinfo:
   # Code from module localcharset:
   # Code from module locale:
   # Code from module localeconv:
+  # Code from module lock:
   # Code from module malloc-gnu:
   # Code from module malloc-posix:
   # Code from module mbrtowc:
@@ -67,10 +71,10 @@ AC_DEFUN([gl_EARLY],
   # Code from module stddef:
   # Code from module stdint:
   # Code from module stdlib:
-  # Code from module strcase:
   # Code from module streq:
-  # Code from module strings:
   # Code from module sys_types:
+  # Code from module threadlib:
+  gl_THREADLIB_EARLY
   # Code from module unistd:
   # Code from module verify:
   # Code from module wchar:
@@ -92,93 +96,87 @@ AC_DEFUN([gl_INIT],
   m4_pushdef([gl_LIBSOURCES_DIR], [])
   gl_COMMON
   gl_source_base='gl'
-gl_FUNC_ALLOCA
-gl_FUNC_BTOWC
-if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then
-  AC_LIBOBJ([btowc])
-  gl_PREREQ_BTOWC
-fi
-gl_WCHAR_MODULE_INDICATOR([btowc])
-gl_BYTESWAP
-gl_CONFIGMAKE_PREP
-AC_SUBST([LIBINTL])
-AC_SUBST([LTLIBINTL])
-gl_LANGINFO_H
-gl_LOCALCHARSET
-LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\""
-AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT])
-gl_LOCALE_H
-gl_FUNC_LOCALECONV
-if test $REPLACE_LOCALECONV = 1; then
-  AC_LIBOBJ([localeconv])
-  gl_PREREQ_LOCALECONV
-fi
-gl_LOCALE_MODULE_INDICATOR([localeconv])
-gl_FUNC_MALLOC_GNU
-if test $REPLACE_MALLOC = 1; then
-  AC_LIBOBJ([malloc])
-fi
-gl_MODULE_INDICATOR([malloc-gnu])
-gl_FUNC_MALLOC_POSIX
-if test $REPLACE_MALLOC = 1; then
-  AC_LIBOBJ([malloc])
-fi
-gl_STDLIB_MODULE_INDICATOR([malloc-posix])
-gl_FUNC_MBRTOWC
-if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
-  AC_LIBOBJ([mbrtowc])
-  gl_PREREQ_MBRTOWC
-fi
-gl_WCHAR_MODULE_INDICATOR([mbrtowc])
-gl_FUNC_MBSINIT
-if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then
-  AC_LIBOBJ([mbsinit])
-  gl_PREREQ_MBSINIT
-fi
-gl_WCHAR_MODULE_INDICATOR([mbsinit])
-gl_FUNC_MBTOWC
-if test $REPLACE_MBTOWC = 1; then
-  AC_LIBOBJ([mbtowc])
-  gl_PREREQ_MBTOWC
-fi
-gl_STDLIB_MODULE_INDICATOR([mbtowc])
-gl_MULTIARCH
-gl_FUNC_NL_LANGINFO
-if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then
-  AC_LIBOBJ([nl_langinfo])
-fi
-gl_LANGINFO_MODULE_INDICATOR([nl_langinfo])
-gl_REGEX
-if test $ac_use_included_regex = yes; then
-  AC_LIBOBJ([regex])
-  gl_PREREQ_REGEX
-fi
-gt_TYPE_SSIZE_T
-AM_STDBOOL_H
-gl_STDDEF_H
-gl_STDINT_H
-gl_STDLIB_H
-gl_STRCASE
-if test $HAVE_STRCASECMP = 0; then
-  AC_LIBOBJ([strcasecmp])
-  gl_PREREQ_STRCASECMP
-fi
-if test $HAVE_STRNCASECMP = 0; then
-  AC_LIBOBJ([strncasecmp])
-  gl_PREREQ_STRNCASECMP
-fi
-gl_HEADER_STRINGS_H
-gl_SYS_TYPES_H
-AC_PROG_MKDIR_P
-gl_UNISTD_H
-gl_WCHAR_H
-gl_FUNC_WCRTOMB
-if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then
-  AC_LIBOBJ([wcrtomb])
-  gl_PREREQ_WCRTOMB
-fi
-gl_WCHAR_MODULE_INDICATOR([wcrtomb])
-gl_WCTYPE_H
+  gl_FUNC_ALLOCA
+  gl_FUNC_BTOWC
+  if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then
+    AC_LIBOBJ([btowc])
+    gl_PREREQ_BTOWC
+  fi
+  gl_WCHAR_MODULE_INDICATOR([btowc])
+  gl_BYTESWAP
+  gl_CONFIGMAKE_PREP
+  AC_REQUIRE([gl_EXTERN_INLINE])
+  AC_SUBST([LIBINTL])
+  AC_SUBST([LTLIBINTL])
+  gl_LANGINFO_H
+  gl_LOCALCHARSET
+  LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\""
+  AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT])
+  gl_LOCALE_H
+  gl_FUNC_LOCALECONV
+  if test $REPLACE_LOCALECONV = 1; then
+    AC_LIBOBJ([localeconv])
+    gl_PREREQ_LOCALECONV
+  fi
+  gl_LOCALE_MODULE_INDICATOR([localeconv])
+  gl_LOCK
+  gl_MODULE_INDICATOR([lock])
+  gl_FUNC_MALLOC_GNU
+  if test $REPLACE_MALLOC = 1; then
+    AC_LIBOBJ([malloc])
+  fi
+  gl_MODULE_INDICATOR([malloc-gnu])
+  gl_FUNC_MALLOC_POSIX
+  if test $REPLACE_MALLOC = 1; then
+    AC_LIBOBJ([malloc])
+  fi
+  gl_STDLIB_MODULE_INDICATOR([malloc-posix])
+  gl_FUNC_MBRTOWC
+  if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
+    AC_LIBOBJ([mbrtowc])
+    gl_PREREQ_MBRTOWC
+  fi
+  gl_WCHAR_MODULE_INDICATOR([mbrtowc])
+  gl_FUNC_MBSINIT
+  if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then
+    AC_LIBOBJ([mbsinit])
+    gl_PREREQ_MBSINIT
+  fi
+  gl_WCHAR_MODULE_INDICATOR([mbsinit])
+  gl_FUNC_MBTOWC
+  if test $REPLACE_MBTOWC = 1; then
+    AC_LIBOBJ([mbtowc])
+    gl_PREREQ_MBTOWC
+  fi
+  gl_STDLIB_MODULE_INDICATOR([mbtowc])
+  gl_MULTIARCH
+  gl_FUNC_NL_LANGINFO
+  if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then
+    AC_LIBOBJ([nl_langinfo])
+  fi
+  gl_LANGINFO_MODULE_INDICATOR([nl_langinfo])
+  gl_REGEX
+  if test $ac_use_included_regex = yes; then
+    AC_LIBOBJ([regex])
+    gl_PREREQ_REGEX
+  fi
+  gt_TYPE_SSIZE_T
+  AM_STDBOOL_H
+  gl_STDDEF_H
+  gl_STDINT_H
+  gl_STDLIB_H
+  gl_SYS_TYPES_H
+  AC_PROG_MKDIR_P
+  gl_THREADLIB
+  gl_UNISTD_H
+  gl_WCHAR_H
+  gl_FUNC_WCRTOMB
+  if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then
+    AC_LIBOBJ([wcrtomb])
+    gl_PREREQ_WCRTOMB
+  fi
+  gl_WCHAR_MODULE_INDICATOR([wcrtomb])
+  gl_WCTYPE_H
   # End of code from modules
   m4_ifval(gl_LIBSOURCES_LIST, [
     m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ ||
@@ -315,6 +313,7 @@ AC_DEFUN([gltests_LIBSOURCES], [
 # 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/config.rpath
   build-aux/snippet/_Noreturn.h
   build-aux/snippet/arg-nonnull.h
   build-aux/snippet/c++defs.h
@@ -324,6 +323,9 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/byteswap.in.h
   lib/config.charset
   lib/gettext.h
+  lib/glthread/lock.c
+  lib/glthread/lock.h
+  lib/glthread/threadlib.c
   lib/langinfo.in.h
   lib/localcharset.c
   lib/localcharset.h
@@ -347,15 +349,14 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/stddef.in.h
   lib/stdint.in.h
   lib/stdlib.in.h
-  lib/strcasecmp.c
   lib/streq.h
-  lib/strings.in.h
-  lib/strncasecmp.c
   lib/sys_types.in.h
+  lib/unistd.c
   lib/unistd.in.h
   lib/verify.h
   lib/wchar.in.h
   lib/wcrtomb.c
+  lib/wctype-h.c
   lib/wctype.in.h
   m4/00gnulib.m4
   m4/alloca.m4
@@ -363,18 +364,24 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/byteswap.m4
   m4/codeset.m4
   m4/configmake.m4
+  m4/eealloc.m4
   m4/extensions.m4
+  m4/extern-inline.m4
   m4/fcntl-o.m4
   m4/glibc21.m4
   m4/gnulib-common.m4
   m4/include_next.m4
   m4/langinfo_h.m4
+  m4/lib-ld.m4
+  m4/lib-link.m4
+  m4/lib-prefix.m4
   m4/localcharset.m4
   m4/locale-fr.m4
   m4/locale-ja.m4
   m4/locale-zh.m4
   m4/locale_h.m4
   m4/localeconv.m4
+  m4/lock.m4
   m4/longlong.m4
   m4/malloc.m4
   m4/mbrtowc.m4
@@ -390,9 +397,8 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/stddef_h.m4
   m4/stdint.m4
   m4/stdlib_h.m4
-  m4/strcase.m4
-  m4/strings_h.m4
   m4/sys_types_h.m4
+  m4/threadlib.m4
   m4/unistd_h.m4
   m4/warn-on-use.m4
   m4/wchar_h.m4
diff --git a/gl/m4/gnulib-tool.m4 b/gl/m4/gnulib-tool.m4
index a09ffc1..f3dea1a 100644
--- a/gl/m4/gnulib-tool.m4
+++ b/gl/m4/gnulib-tool.m4
@@ -1,5 +1,5 @@
 # gnulib-tool.m4 serial 2
-dnl Copyright (C) 2004-2005, 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2004-2005, 2009-2013 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.
diff --git a/gl/m4/include_next.m4 b/gl/m4/include_next.m4
index a60a261..108d945 100644
--- a/gl/m4/include_next.m4
+++ b/gl/m4/include_next.m4
@@ -1,5 +1,5 @@
 # include_next.m4 serial 23
-dnl Copyright (C) 2006-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2006-2013 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.
diff --git a/gl/m4/langinfo_h.m4 b/gl/m4/langinfo_h.m4
index b93fe70..73bef8b 100644
--- a/gl/m4/langinfo_h.m4
+++ b/gl/m4/langinfo_h.m4
@@ -1,5 +1,5 @@
 # langinfo_h.m4 serial 7
-dnl Copyright (C) 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-2013 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.
diff --git a/gl/m4/lib-ld.m4 b/gl/m4/lib-ld.m4
new file mode 100644
index 0000000..c145e47
--- /dev/null
+++ b/gl/m4/lib-ld.m4
@@ -0,0 +1,119 @@
+# lib-ld.m4 serial 6
+dnl Copyright (C) 1996-2003, 2009-2013 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 Subroutines of libtool.m4,
+dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid
+dnl collision with libtool.m4.
+
+dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no.
+AC_DEFUN([AC_LIB_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_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'*)
+  acl_cv_prog_gnu_ld=yes
+  ;;
+*)
+  acl_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$acl_cv_prog_gnu_ld
+])
+
+dnl From libtool-2.4. Sets the variable LD.
+AC_DEFUN([AC_LIB_PROG_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])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
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+  # contains only /bin. Note that ksh looks also at the FPATH variable,
+  # so we have to set that as well for the test.
+  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
+
+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([acl_cv_path_LD],
+[if test -z "$LD"; then
+  acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$acl_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      acl_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 `"$acl_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="$acl_save_ifs"
+else
+  acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$acl_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])
+AC_LIB_PROG_LD_GNU
+])
diff --git a/gl/m4/lib-link.m4 b/gl/m4/lib-link.m4
new file mode 100644
index 0000000..073f040
--- /dev/null
+++ b/gl/m4/lib-link.m4
@@ -0,0 +1,777 @@
+# lib-link.m4 serial 26 (gettext-0.18.2)
+dnl Copyright (C) 2001-2013 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_PREREQ([2.54])
+
+dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
+dnl augments the CPPFLAGS variable.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS],
+[
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  AC_REQUIRE([AC_LIB_RPATH])
+  pushdef([Name],[m4_translit([$1],[./+-], [____])])
+  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
+    AC_LIB_LINKFLAGS_BODY([$1], [$2])
+    ac_cv_lib[]Name[]_libs="$LIB[]NAME"
+    ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
+    ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
+    ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
+  ])
+  LIB[]NAME="$ac_cv_lib[]Name[]_libs"
+  LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
+  INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
+  LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
+  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+  AC_SUBST([LIB]NAME)
+  AC_SUBST([LTLIB]NAME)
+  AC_SUBST([LIB]NAME[_PREFIX])
+  dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
+  dnl results of this search when this library appears as a dependency.
+  HAVE_LIB[]NAME=yes
+  popdef([NAME])
+  popdef([Name])
+])
+
+dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
+dnl searches for libname and the libraries corresponding to explicit and
+dnl implicit dependencies, together with the specified include files and
+dnl the ability to compile and link the specified testcode. The missing-message
+dnl defaults to 'no' and may contain additional hints for the user.
+dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
+dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
+dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
+dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
+[
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  AC_REQUIRE([AC_LIB_RPATH])
+  pushdef([Name],[m4_translit([$1],[./+-], [____])])
+  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+
+  dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
+  dnl accordingly.
+  AC_LIB_LINKFLAGS_BODY([$1], [$2])
+
+  dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
+  dnl because if the user has installed lib[]Name and not disabled its use
+  dnl via --without-lib[]Name-prefix, he wants to use it.
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+
+  AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
+    ac_save_LIBS="$LIBS"
+    dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
+    dnl because these -l options might require -L options that are present in
+    dnl LIBS. -l options benefit only from the -L options listed before it.
+    dnl Otherwise, add it to the front of LIBS, because it may be a static
+    dnl library that depends on another static library that is present in LIBS.
+    dnl Static libraries benefit only from the static libraries listed after
+    dnl it.
+    case " $LIB[]NAME" in
+      *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
+      *)       LIBS="$LIB[]NAME $LIBS" ;;
+    esac
+    AC_LINK_IFELSE(
+      [AC_LANG_PROGRAM([[$3]], [[$4]])],
+      [ac_cv_lib[]Name=yes],
+      [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
+    LIBS="$ac_save_LIBS"
+  ])
+  if test "$ac_cv_lib[]Name" = yes; then
+    HAVE_LIB[]NAME=yes
+    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
+    AC_MSG_CHECKING([how to link with lib[]$1])
+    AC_MSG_RESULT([$LIB[]NAME])
+  else
+    HAVE_LIB[]NAME=no
+    dnl If $LIB[]NAME didn't lead to a usable library, we don't need
+    dnl $INC[]NAME either.
+    CPPFLAGS="$ac_save_CPPFLAGS"
+    LIB[]NAME=
+    LTLIB[]NAME=
+    LIB[]NAME[]_PREFIX=
+  fi
+  AC_SUBST([HAVE_LIB]NAME)
+  AC_SUBST([LIB]NAME)
+  AC_SUBST([LTLIB]NAME)
+  AC_SUBST([LIB]NAME[_PREFIX])
+  popdef([NAME])
+  popdef([Name])
+])
+
+dnl Determine the platform dependent parameters needed to use rpath:
+dnl   acl_libext,
+dnl   acl_shlibext,
+dnl   acl_libname_spec,
+dnl   acl_library_names_spec,
+dnl   acl_hardcode_libdir_flag_spec,
+dnl   acl_hardcode_libdir_separator,
+dnl   acl_hardcode_direct,
+dnl   acl_hardcode_minus_L.
+AC_DEFUN([AC_LIB_RPATH],
+[
+  dnl Tell automake >= 1.10 to complain if config.rpath is missing.
+  m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
+  AC_REQUIRE([AC_PROG_CC])                dnl we use $CC, $GCC, $LDFLAGS
+  AC_REQUIRE([AC_LIB_PROG_LD])            dnl we use $LD, $with_gnu_ld
+  AC_REQUIRE([AC_CANONICAL_HOST])         dnl we use $host
+  AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
+  AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
+    CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
+    ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
+    . ./conftest.sh
+    rm -f ./conftest.sh
+    acl_cv_rpath=done
+  ])
+  wl="$acl_cv_wl"
+  acl_libext="$acl_cv_libext"
+  acl_shlibext="$acl_cv_shlibext"
+  acl_libname_spec="$acl_cv_libname_spec"
+  acl_library_names_spec="$acl_cv_library_names_spec"
+  acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+  acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+  acl_hardcode_direct="$acl_cv_hardcode_direct"
+  acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
+  dnl Determine whether the user wants rpath handling at all.
+  AC_ARG_ENABLE([rpath],
+    [  --disable-rpath         do not hardcode runtime library paths],
+    :, enable_rpath=yes)
+])
+
+dnl AC_LIB_FROMPACKAGE(name, package)
+dnl declares that libname comes from the given package. The configure file
+dnl will then not have a --with-libname-prefix option but a
+dnl --with-package-prefix option. Several libraries can come from the same
+dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
+dnl macro call that searches for libname.
+AC_DEFUN([AC_LIB_FROMPACKAGE],
+[
+  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  define([acl_frompackage_]NAME, [$2])
+  popdef([NAME])
+  pushdef([PACK],[$2])
+  pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
+                                     [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  define([acl_libsinpackage_]PACKUP,
+    m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1])
+  popdef([PACKUP])
+  popdef([PACK])
+])
+
+dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
+dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
+dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
+[
+  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
+  pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
+                                     [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
+  dnl Autoconf >= 2.61 supports dots in --with options.
+  pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
+  dnl By default, look in $includedir and $libdir.
+  use_additional=yes
+  AC_LIB_WITH_FINAL_PREFIX([
+    eval additional_includedir=\"$includedir\"
+    eval additional_libdir=\"$libdir\"
+  ])
+  AC_ARG_WITH(P_A_C_K[-prefix],
+[[  --with-]]P_A_C_K[[-prefix[=DIR]  search for ]PACKLIBS[ in DIR/include and DIR/lib
+  --without-]]P_A_C_K[[-prefix     don't search for ]PACKLIBS[ in includedir and libdir]],
+[
+    if test "X$withval" = "Xno"; then
+      use_additional=no
+    else
+      if test "X$withval" = "X"; then
+        AC_LIB_WITH_FINAL_PREFIX([
+          eval additional_includedir=\"$includedir\"
+          eval additional_libdir=\"$libdir\"
+        ])
+      else
+        additional_includedir="$withval/include"
+        additional_libdir="$withval/$acl_libdirstem"
+        if test "$acl_libdirstem2" != "$acl_libdirstem" \
+           && ! test -d "$withval/$acl_libdirstem"; then
+          additional_libdir="$withval/$acl_libdirstem2"
+        fi
+      fi
+    fi
+])
+  dnl Search the library and its dependencies in $additional_libdir and
+  dnl $LDFLAGS. Using breadth-first-seach.
+  LIB[]NAME=
+  LTLIB[]NAME=
+  INC[]NAME=
+  LIB[]NAME[]_PREFIX=
+  dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
+  dnl computed. So it has to be reset here.
+  HAVE_LIB[]NAME=
+  rpathdirs=
+  ltrpathdirs=
+  names_already_handled=
+  names_next_round='$1 $2'
+  while test -n "$names_next_round"; do
+    names_this_round="$names_next_round"
+    names_next_round=
+    for name in $names_this_round; do
+      already_handled=
+      for n in $names_already_handled; do
+        if test "$n" = "$name"; then
+          already_handled=yes
+          break
+        fi
+      done
+      if test -z "$already_handled"; then
+        names_already_handled="$names_already_handled $name"
+        dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
+        dnl or AC_LIB_HAVE_LINKFLAGS call.
+        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
+        eval value=\"\$HAVE_LIB$uppername\"
+        if test -n "$value"; then
+          if test "$value" = yes; then
+            eval value=\"\$LIB$uppername\"
+            test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
+            eval value=\"\$LTLIB$uppername\"
+            test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
+          else
+            dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
+            dnl that this library doesn't exist. So just drop it.
+            :
+          fi
+        else
+          dnl Search the library lib$name in $additional_libdir and $LDFLAGS
+          dnl and the already constructed $LIBNAME/$LTLIBNAME.
+          found_dir=
+          found_la=
+          found_so=
+          found_a=
+          eval libname=\"$acl_libname_spec\"    # typically: libname=lib$name
+          if test -n "$acl_shlibext"; then
+            shrext=".$acl_shlibext"             # typically: shrext=.so
+          else
+            shrext=
+          fi
+          if test $use_additional = yes; then
+            dir="$additional_libdir"
+            dnl The same code as in the loop below:
+            dnl First look for a shared library.
+            if test -n "$acl_shlibext"; then
+              if test -f "$dir/$libname$shrext"; then
+                found_dir="$dir"
+                found_so="$dir/$libname$shrext"
+              else
+                if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                  ver=`(cd "$dir" && \
+                        for f in "$libname$shrext".*; do echo "$f"; done \
+                        | sed -e "s,^$libname$shrext\\\\.,," \
+                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                        | sed 1q ) 2>/dev/null`
+                  if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                    found_dir="$dir"
+                    found_so="$dir/$libname$shrext.$ver"
+                  fi
+                else
+                  eval library_names=\"$acl_library_names_spec\"
+                  for f in $library_names; do
+                    if test -f "$dir/$f"; then
+                      found_dir="$dir"
+                      found_so="$dir/$f"
+                      break
+                    fi
+                  done
+                fi
+              fi
+            fi
+            dnl Then look for a static library.
+            if test "X$found_dir" = "X"; then
+              if test -f "$dir/$libname.$acl_libext"; then
+                found_dir="$dir"
+                found_a="$dir/$libname.$acl_libext"
+              fi
+            fi
+            if test "X$found_dir" != "X"; then
+              if test -f "$dir/$libname.la"; then
+                found_la="$dir/$libname.la"
+              fi
+            fi
+          fi
+          if test "X$found_dir" = "X"; then
+            for x in $LDFLAGS $LTLIB[]NAME; do
+              AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+              case "$x" in
+                -L*)
+                  dir=`echo "X$x" | sed -e 's/^X-L//'`
+                  dnl First look for a shared library.
+                  if test -n "$acl_shlibext"; then
+                    if test -f "$dir/$libname$shrext"; then
+                      found_dir="$dir"
+                      found_so="$dir/$libname$shrext"
+                    else
+                      if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                        ver=`(cd "$dir" && \
+                              for f in "$libname$shrext".*; do echo "$f"; done \
+                              | sed -e "s,^$libname$shrext\\\\.,," \
+                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                              | sed 1q ) 2>/dev/null`
+                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                          found_dir="$dir"
+                          found_so="$dir/$libname$shrext.$ver"
+                        fi
+                      else
+                        eval library_names=\"$acl_library_names_spec\"
+                        for f in $library_names; do
+                          if test -f "$dir/$f"; then
+                            found_dir="$dir"
+                            found_so="$dir/$f"
+                            break
+                          fi
+                        done
+                      fi
+                    fi
+                  fi
+                  dnl Then look for a static library.
+                  if test "X$found_dir" = "X"; then
+                    if test -f "$dir/$libname.$acl_libext"; then
+                      found_dir="$dir"
+                      found_a="$dir/$libname.$acl_libext"
+                    fi
+                  fi
+                  if test "X$found_dir" != "X"; then
+                    if test -f "$dir/$libname.la"; then
+                      found_la="$dir/$libname.la"
+                    fi
+                  fi
+                  ;;
+              esac
+              if test "X$found_dir" != "X"; then
+                break
+              fi
+            done
+          fi
+          if test "X$found_dir" != "X"; then
+            dnl Found the library.
+            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
+            if test "X$found_so" != "X"; then
+              dnl Linking with a shared library. We attempt to hardcode its
+              dnl directory into the executable's runpath, unless it's the
+              dnl standard /usr/lib.
+              if test "$enable_rpath" = no \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem" \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+                dnl No hardcoding is needed.
+                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+              else
+                dnl Use an explicit option to hardcode DIR into the resulting
+                dnl binary.
+                dnl Potentially add DIR to ltrpathdirs.
+                dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+                haveit=
+                for x in $ltrpathdirs; do
+                  if test "X$x" = "X$found_dir"; then
+                    haveit=yes
+                    break
+                  fi
+                done
+                if test -z "$haveit"; then
+                  ltrpathdirs="$ltrpathdirs $found_dir"
+                fi
+                dnl The hardcoding into $LIBNAME is system dependent.
+                if test "$acl_hardcode_direct" = yes; then
+                  dnl Using DIR/libNAME.so during linking hardcodes DIR into the
+                  dnl resulting binary.
+                  LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+                else
+                  if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+                    dnl Use an explicit option to hardcode DIR into the resulting
+                    dnl binary.
+                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+                    dnl Potentially add DIR to rpathdirs.
+                    dnl The rpathdirs will be appended to $LIBNAME at the end.
+                    haveit=
+                    for x in $rpathdirs; do
+                      if test "X$x" = "X$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      rpathdirs="$rpathdirs $found_dir"
+                    fi
+                  else
+                    dnl Rely on "-L$found_dir".
+                    dnl But don't add it if it's already contained in the LDFLAGS
+                    dnl or the already constructed $LIBNAME
+                    haveit=
+                    for x in $LDFLAGS $LIB[]NAME; do
+                      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+                      if test "X$x" = "X-L$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
+                    fi
+                    if test "$acl_hardcode_minus_L" != no; then
+                      dnl FIXME: Not sure whether we should use
+                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+                      dnl here.
+                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+                    else
+                      dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
+                      dnl here, because this doesn't fit in flags passed to the
+                      dnl compiler. So give up. No hardcoding. This affects only
+                      dnl very old systems.
+                      dnl FIXME: Not sure whether we should use
+                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+                      dnl here.
+                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+                    fi
+                  fi
+                fi
+              fi
+            else
+              if test "X$found_a" != "X"; then
+                dnl Linking with a static library.
+                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
+              else
+                dnl We shouldn't come here, but anyway it's good to have a
+                dnl fallback.
+                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
+              fi
+            fi
+            dnl Assume the include files are nearby.
+            additional_includedir=
+            case "$found_dir" in
+              */$acl_libdirstem | */$acl_libdirstem/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+                if test "$name" = '$1'; then
+                  LIB[]NAME[]_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
+              */$acl_libdirstem2 | */$acl_libdirstem2/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
+                if test "$name" = '$1'; then
+                  LIB[]NAME[]_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
+            esac
+            if test "X$additional_includedir" != "X"; then
+              dnl Potentially add $additional_includedir to $INCNAME.
+              dnl But don't add it
+              dnl   1. if it's the standard /usr/include,
+              dnl   2. if it's /usr/local/include and we are using GCC on Linux,
+              dnl   3. if it's already present in $CPPFLAGS or the already
+              dnl      constructed $INCNAME,
+              dnl   4. if it doesn't exist as a directory.
+              if test "X$additional_includedir" != "X/usr/include"; then
+                haveit=
+                if test "X$additional_includedir" = "X/usr/local/include"; then
+                  if test -n "$GCC"; then
+                    case $host_os in
+                      linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+                    esac
+                  fi
+                fi
+                if test -z "$haveit"; then
+                  for x in $CPPFLAGS $INC[]NAME; do
+                    AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+                    if test "X$x" = "X-I$additional_includedir"; then
+                      haveit=yes
+                      break
+                    fi
+                  done
+                  if test -z "$haveit"; then
+                    if test -d "$additional_includedir"; then
+                      dnl Really add $additional_includedir to $INCNAME.
+                      INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
+                    fi
+                  fi
+                fi
+              fi
+            fi
+            dnl Look for dependencies.
+            if test -n "$found_la"; then
+              dnl Read the .la file. It defines the variables
+              dnl dlname, library_names, old_library, dependency_libs, current,
+              dnl age, revision, installed, dlopen, dlpreopen, libdir.
+              save_libdir="$libdir"
+              case "$found_la" in
+                */* | *\\*) . "$found_la" ;;
+                *) . "./$found_la" ;;
+              esac
+              libdir="$save_libdir"
+              dnl We use only dependency_libs.
+              for dep in $dependency_libs; do
+                case "$dep" in
+                  -L*)
+                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+                    dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
+                    dnl But don't add it
+                    dnl   1. if it's the standard /usr/lib,
+                    dnl   2. if it's /usr/local/lib and we are using GCC on Linux,
+                    dnl   3. if it's already present in $LDFLAGS or the already
+                    dnl      constructed $LIBNAME,
+                    dnl   4. if it doesn't exist as a directory.
+                    if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
+                       && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+                      haveit=
+                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
+                         || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+                        if test -n "$GCC"; then
+                          case $host_os in
+                            linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+                          esac
+                        fi
+                      fi
+                      if test -z "$haveit"; then
+                        haveit=
+                        for x in $LDFLAGS $LIB[]NAME; do
+                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                            dnl Really add $additional_libdir to $LIBNAME.
+                            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
+                          fi
+                        fi
+                        haveit=
+                        for x in $LDFLAGS $LTLIB[]NAME; do
+                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                            dnl Really add $additional_libdir to $LTLIBNAME.
+                            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
+                          fi
+                        fi
+                      fi
+                    fi
+                    ;;
+                  -R*)
+                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
+                    if test "$enable_rpath" != no; then
+                      dnl Potentially add DIR to rpathdirs.
+                      dnl The rpathdirs will be appended to $LIBNAME at the end.
+                      haveit=
+                      for x in $rpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        rpathdirs="$rpathdirs $dir"
+                      fi
+                      dnl Potentially add DIR to ltrpathdirs.
+                      dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+                      haveit=
+                      for x in $ltrpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        ltrpathdirs="$ltrpathdirs $dir"
+                      fi
+                    fi
+                    ;;
+                  -l*)
+                    dnl Handle this in the next round.
+                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+                    ;;
+                  *.la)
+                    dnl Handle this in the next round. Throw away the .la's
+                    dnl directory; it is already contained in a preceding -L
+                    dnl option.
+                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+                    ;;
+                  *)
+                    dnl Most likely an immediate library name.
+                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
+                    LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
+                    ;;
+                esac
+              done
+            fi
+          else
+            dnl Didn't find the library; assume it is in the system directories
+            dnl known to the linker and runtime loader. (All the system
+            dnl directories known to the linker should also be known to the
+            dnl runtime loader, otherwise the system is severely misconfigured.)
+            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
+          fi
+        fi
+      fi
+    done
+  done
+  if test "X$rpathdirs" != "X"; then
+    if test -n "$acl_hardcode_libdir_separator"; then
+      dnl Weird platform: only the last -rpath option counts, the user must
+      dnl pass all path elements in one option. We can arrange that for a
+      dnl single library, but not when more than one $LIBNAMEs are used.
+      alldirs=
+      for found_dir in $rpathdirs; do
+        alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+      done
+      dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
+      acl_save_libdir="$libdir"
+      libdir="$alldirs"
+      eval flag=\"$acl_hardcode_libdir_flag_spec\"
+      libdir="$acl_save_libdir"
+      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+    else
+      dnl The -rpath options are cumulative.
+      for found_dir in $rpathdirs; do
+        acl_save_libdir="$libdir"
+        libdir="$found_dir"
+        eval flag=\"$acl_hardcode_libdir_flag_spec\"
+        libdir="$acl_save_libdir"
+        LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+      done
+    fi
+  fi
+  if test "X$ltrpathdirs" != "X"; then
+    dnl When using libtool, the option that works for both libraries and
+    dnl executables is -R. The -R options are cumulative.
+    for found_dir in $ltrpathdirs; do
+      LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
+    done
+  fi
+  popdef([P_A_C_K])
+  popdef([PACKLIBS])
+  popdef([PACKUP])
+  popdef([PACK])
+  popdef([NAME])
+])
+
+dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
+dnl unless already present in VAR.
+dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
+dnl contains two or three consecutive elements that belong together.
+AC_DEFUN([AC_LIB_APPENDTOVAR],
+[
+  for element in [$2]; do
+    haveit=
+    for x in $[$1]; do
+      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+      if test "X$x" = "X$element"; then
+        haveit=yes
+        break
+      fi
+    done
+    if test -z "$haveit"; then
+      [$1]="${[$1]}${[$1]:+ }$element"
+    fi
+  done
+])
+
+dnl For those cases where a variable contains several -L and -l options
+dnl referring to unknown libraries and directories, this macro determines the
+dnl necessary additional linker options for the runtime path.
+dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
+dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
+dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
+dnl otherwise linking without libtool is assumed.
+AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
+[
+  AC_REQUIRE([AC_LIB_RPATH])
+  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+  $1=
+  if test "$enable_rpath" != no; then
+    if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+      dnl Use an explicit option to hardcode directories into the resulting
+      dnl binary.
+      rpathdirs=
+      next=
+      for opt in $2; do
+        if test -n "$next"; then
+          dir="$next"
+          dnl No need to hardcode the standard /usr/lib.
+          if test "X$dir" != "X/usr/$acl_libdirstem" \
+             && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+            rpathdirs="$rpathdirs $dir"
+          fi
+          next=
+        else
+          case $opt in
+            -L) next=yes ;;
+            -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
+                 dnl No need to hardcode the standard /usr/lib.
+                 if test "X$dir" != "X/usr/$acl_libdirstem" \
+                    && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+                   rpathdirs="$rpathdirs $dir"
+                 fi
+                 next= ;;
+            *) next= ;;
+          esac
+        fi
+      done
+      if test "X$rpathdirs" != "X"; then
+        if test -n ""$3""; then
+          dnl libtool is used for linking. Use -R options.
+          for dir in $rpathdirs; do
+            $1="${$1}${$1:+ }-R$dir"
+          done
+        else
+          dnl The linker is used for linking directly.
+          if test -n "$acl_hardcode_libdir_separator"; then
+            dnl Weird platform: only the last -rpath option counts, the user
+            dnl must pass all path elements in one option.
+            alldirs=
+            for dir in $rpathdirs; do
+              alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
+            done
+            acl_save_libdir="$libdir"
+            libdir="$alldirs"
+            eval flag=\"$acl_hardcode_libdir_flag_spec\"
+            libdir="$acl_save_libdir"
+            $1="$flag"
+          else
+            dnl The -rpath options are cumulative.
+            for dir in $rpathdirs; do
+              acl_save_libdir="$libdir"
+              libdir="$dir"
+              eval flag=\"$acl_hardcode_libdir_flag_spec\"
+              libdir="$acl_save_libdir"
+              $1="${$1}${$1:+ }$flag"
+            done
+          fi
+        fi
+      fi
+    fi
+  fi
+  AC_SUBST([$1])
+])
diff --git a/gl/m4/lib-prefix.m4 b/gl/m4/lib-prefix.m4
new file mode 100644
index 0000000..60908e8
--- /dev/null
+++ b/gl/m4/lib-prefix.m4
@@ -0,0 +1,224 @@
+# lib-prefix.m4 serial 7 (gettext-0.18)
+dnl Copyright (C) 2001-2005, 2008-2013 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 AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
+dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
+dnl require excessive bracketing.
+ifdef([AC_HELP_STRING],
+[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
+[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
+
+dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
+dnl to access previously installed libraries. The basic assumption is that
+dnl a user will want packages to use other packages he previously installed
+dnl with the same --prefix option.
+dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
+dnl libraries, but is otherwise very convenient.
+AC_DEFUN([AC_LIB_PREFIX],
+[
+  AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  dnl By default, look in $includedir and $libdir.
+  use_additional=yes
+  AC_LIB_WITH_FINAL_PREFIX([
+    eval additional_includedir=\"$includedir\"
+    eval additional_libdir=\"$libdir\"
+  ])
+  AC_LIB_ARG_WITH([lib-prefix],
+[  --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
+  --without-lib-prefix    don't search for libraries in includedir and libdir],
+[
+    if test "X$withval" = "Xno"; then
+      use_additional=no
+    else
+      if test "X$withval" = "X"; then
+        AC_LIB_WITH_FINAL_PREFIX([
+          eval additional_includedir=\"$includedir\"
+          eval additional_libdir=\"$libdir\"
+        ])
+      else
+        additional_includedir="$withval/include"
+        additional_libdir="$withval/$acl_libdirstem"
+      fi
+    fi
+])
+  if test $use_additional = yes; then
+    dnl Potentially add $additional_includedir to $CPPFLAGS.
+    dnl But don't add it
+    dnl   1. if it's the standard /usr/include,
+    dnl   2. if it's already present in $CPPFLAGS,
+    dnl   3. if it's /usr/local/include and we are using GCC on Linux,
+    dnl   4. if it doesn't exist as a directory.
+    if test "X$additional_includedir" != "X/usr/include"; then
+      haveit=
+      for x in $CPPFLAGS; do
+        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+        if test "X$x" = "X-I$additional_includedir"; then
+          haveit=yes
+          break
+        fi
+      done
+      if test -z "$haveit"; then
+        if test "X$additional_includedir" = "X/usr/local/include"; then
+          if test -n "$GCC"; then
+            case $host_os in
+              linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+            esac
+          fi
+        fi
+        if test -z "$haveit"; then
+          if test -d "$additional_includedir"; then
+            dnl Really add $additional_includedir to $CPPFLAGS.
+            CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
+          fi
+        fi
+      fi
+    fi
+    dnl Potentially add $additional_libdir to $LDFLAGS.
+    dnl But don't add it
+    dnl   1. if it's the standard /usr/lib,
+    dnl   2. if it's already present in $LDFLAGS,
+    dnl   3. if it's /usr/local/lib and we are using GCC on Linux,
+    dnl   4. if it doesn't exist as a directory.
+    if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
+      haveit=
+      for x in $LDFLAGS; do
+        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+        if test "X$x" = "X-L$additional_libdir"; then
+          haveit=yes
+          break
+        fi
+      done
+      if test -z "$haveit"; then
+        if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
+          if test -n "$GCC"; then
+            case $host_os in
+              linux*) haveit=yes;;
+            esac
+          fi
+        fi
+        if test -z "$haveit"; then
+          if test -d "$additional_libdir"; then
+            dnl Really add $additional_libdir to $LDFLAGS.
+            LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
+          fi
+        fi
+      fi
+    fi
+  fi
+])
+
+dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
+dnl acl_final_exec_prefix, containing the values to which $prefix and
+dnl $exec_prefix will expand at the end of the configure script.
+AC_DEFUN([AC_LIB_PREPARE_PREFIX],
+[
+  dnl Unfortunately, prefix and exec_prefix get only finally determined
+  dnl at the end of configure.
+  if test "X$prefix" = "XNONE"; then
+    acl_final_prefix="$ac_default_prefix"
+  else
+    acl_final_prefix="$prefix"
+  fi
+  if test "X$exec_prefix" = "XNONE"; then
+    acl_final_exec_prefix='${prefix}'
+  else
+    acl_final_exec_prefix="$exec_prefix"
+  fi
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+  prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
+dnl variables prefix and exec_prefix bound to the values they will have
+dnl at the end of the configure script.
+AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
+[
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  $1
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_PREPARE_MULTILIB creates
+dnl - a variable acl_libdirstem, containing the basename of the libdir, either
+dnl   "lib" or "lib64" or "lib/64",
+dnl - a variable acl_libdirstem2, as a secondary possible value for
+dnl   acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
+dnl   "lib/amd64".
+AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
+[
+  dnl There is no formal standard regarding lib and lib64.
+  dnl On glibc systems, the current practice is that on a system supporting
+  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+  dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
+  dnl the compiler's default mode by looking at the compiler's library search
+  dnl path. If at least one of its elements ends in /lib64 or points to a
+  dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
+  dnl Otherwise we use the default, namely "lib".
+  dnl On Solaris systems, the current practice is that on a system supporting
+  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+  dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
+  dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  acl_libdirstem=lib
+  acl_libdirstem2=
+  case "$host_os" in
+    solaris*)
+      dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
+      dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
+      dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
+      dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
+      dnl symlink is missing, so we set acl_libdirstem2 too.
+      AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
+        [AC_EGREP_CPP([sixtyfour bits], [
+#ifdef _LP64
+sixtyfour bits
+#endif
+           ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
+        ])
+      if test $gl_cv_solaris_64bit = yes; then
+        acl_libdirstem=lib/64
+        case "$host_cpu" in
+          sparc*)        acl_libdirstem2=lib/sparcv9 ;;
+          i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+        esac
+      fi
+      ;;
+    *)
+      searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+      if test -n "$searchpath"; then
+        acl_save_IFS="${IFS= 	}"; IFS=":"
+        for searchdir in $searchpath; do
+          if test -d "$searchdir"; then
+            case "$searchdir" in
+              */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+              */../ | */.. )
+                # Better ignore directories of this form. They are misleading.
+                ;;
+              *) searchdir=`cd "$searchdir" && pwd`
+                 case "$searchdir" in
+                   */lib64 ) acl_libdirstem=lib64 ;;
+                 esac ;;
+            esac
+          fi
+        done
+        IFS="$acl_save_IFS"
+      fi
+      ;;
+  esac
+  test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+])
diff --git a/gl/m4/localcharset.m4 b/gl/m4/localcharset.m4
index 8010379..2e93e58 100644
--- a/gl/m4/localcharset.m4
+++ b/gl/m4/localcharset.m4
@@ -1,5 +1,5 @@
 # localcharset.m4 serial 7
-dnl Copyright (C) 2002, 2004, 2006, 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2002, 2004, 2006, 2009-2013 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.
diff --git a/gl/m4/locale-fr.m4 b/gl/m4/locale-fr.m4
index 71b6847..ef199e3 100644
--- a/gl/m4/locale-fr.m4
+++ b/gl/m4/locale-fr.m4
@@ -1,5 +1,5 @@
 # locale-fr.m4 serial 17
-dnl Copyright (C) 2003, 2005-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2005-2013 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.
diff --git a/gl/m4/locale-ja.m4 b/gl/m4/locale-ja.m4
index 5ba0e43..132a3e7 100644
--- a/gl/m4/locale-ja.m4
+++ b/gl/m4/locale-ja.m4
@@ -1,5 +1,5 @@
 # locale-ja.m4 serial 12
-dnl Copyright (C) 2003, 2005-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2005-2013 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.
diff --git a/gl/m4/locale-zh.m4 b/gl/m4/locale-zh.m4
index e5502b2..4eed73f 100644
--- a/gl/m4/locale-zh.m4
+++ b/gl/m4/locale-zh.m4
@@ -1,5 +1,5 @@
 # locale-zh.m4 serial 12
-dnl Copyright (C) 2003, 2005-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2005-2013 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.
diff --git a/gl/m4/locale_h.m4 b/gl/m4/locale_h.m4
index c0f4d52..8bd12e8 100644
--- a/gl/m4/locale_h.m4
+++ b/gl/m4/locale_h.m4
@@ -1,5 +1,5 @@
 # locale_h.m4 serial 19
-dnl Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2007, 2009-2013 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.
diff --git a/gl/m4/localeconv.m4 b/gl/m4/localeconv.m4
index 5fae06d..b8bb596 100644
--- a/gl/m4/localeconv.m4
+++ b/gl/m4/localeconv.m4
@@ -1,5 +1,5 @@
 # localeconv.m4 serial 1
-dnl Copyright (C) 2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2012-2013 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.
diff --git a/gl/m4/lock.m4 b/gl/m4/lock.m4
new file mode 100644
index 0000000..aae1701
--- /dev/null
+++ b/gl/m4/lock.m4
@@ -0,0 +1,42 @@
+# lock.m4 serial 13 (gettext-0.18.2)
+dnl Copyright (C) 2005-2013 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([gl_LOCK],
+[
+  AC_REQUIRE([gl_THREADLIB])
+  if test "$gl_threads_api" = posix; then
+    # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the
+    # pthread_rwlock_* functions.
+    AC_CHECK_TYPE([pthread_rwlock_t],
+      [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],
+         [Define if the POSIX multithreading library has read/write locks.])],
+      [],
+      [#include <pthread.h>])
+    # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
+    AC_COMPILE_IFELSE([
+      AC_LANG_PROGRAM(
+        [[#include <pthread.h>]],
+        [[
+#if __FreeBSD__ == 4
+error "No, in FreeBSD 4.0 recursive mutexes actually don't work."
+#elif (defined __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ \
+       && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)
+error "No, in Mac OS X < 10.7 recursive mutexes actually don't work."
+#else
+int x = (int)PTHREAD_MUTEX_RECURSIVE;
+return !x;
+#endif
+        ]])],
+      [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], [1],
+         [Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE.])])
+  fi
+  gl_PREREQ_LOCK
+])
+
+# Prerequisites of lib/glthread/lock.c.
+AC_DEFUN([gl_PREREQ_LOCK], [:])
diff --git a/gl/m4/longlong.m4 b/gl/m4/longlong.m4
index b9c65c7..3af6ab5 100644
--- a/gl/m4/longlong.m4
+++ b/gl/m4/longlong.m4
@@ -1,5 +1,5 @@
 # longlong.m4 serial 17
-dnl Copyright (C) 1999-2007, 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 1999-2007, 2009-2013 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.
diff --git a/gl/m4/malloc.m4 b/gl/m4/malloc.m4
index 8fa48e9..4b24a0b 100644
--- a/gl/m4/malloc.m4
+++ b/gl/m4/malloc.m4
@@ -1,5 +1,5 @@
 # malloc.m4 serial 14
-dnl Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2007, 2009-2013 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.
diff --git a/gl/m4/mbrtowc.m4 b/gl/m4/mbrtowc.m4
index 8f829c8..4c9f388 100644
--- a/gl/m4/mbrtowc.m4
+++ b/gl/m4/mbrtowc.m4
@@ -1,5 +1,5 @@
 # mbrtowc.m4 serial 25
-dnl Copyright (C) 2001-2002, 2004-2005, 2008-2012 Free Software Foundation,
+dnl Copyright (C) 2001-2002, 2004-2005, 2008-2013 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,
diff --git a/gl/m4/mbsinit.m4 b/gl/m4/mbsinit.m4
index da56c3d..2e6d092 100644
--- a/gl/m4/mbsinit.m4
+++ b/gl/m4/mbsinit.m4
@@ -1,5 +1,5 @@
 # mbsinit.m4 serial 8
-dnl Copyright (C) 2008, 2010-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2008, 2010-2013 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.
diff --git a/gl/m4/mbstate_t.m4 b/gl/m4/mbstate_t.m4
index 61a8190..ed00117 100644
--- a/gl/m4/mbstate_t.m4
+++ b/gl/m4/mbstate_t.m4
@@ -1,5 +1,5 @@
 # mbstate_t.m4 serial 13
-dnl Copyright (C) 2000-2002, 2008-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2000-2002, 2008-2013 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.
diff --git a/gl/m4/mbtowc.m4 b/gl/m4/mbtowc.m4
index fec0d25..e479461 100644
--- a/gl/m4/mbtowc.m4
+++ b/gl/m4/mbtowc.m4
@@ -1,5 +1,5 @@
 # mbtowc.m4 serial 2
-dnl Copyright (C) 2011-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-2013 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.
diff --git a/gl/m4/multiarch.m4 b/gl/m4/multiarch.m4
index 0c288b8..552ec7e 100644
--- a/gl/m4/multiarch.m4
+++ b/gl/m4/multiarch.m4
@@ -1,5 +1,5 @@
 # multiarch.m4 serial 7
-dnl Copyright (C) 2008-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-2013 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.
diff --git a/gl/m4/nl_langinfo.m4 b/gl/m4/nl_langinfo.m4
index 80fe60d..25e2101 100644
--- a/gl/m4/nl_langinfo.m4
+++ b/gl/m4/nl_langinfo.m4
@@ -1,5 +1,5 @@
 # nl_langinfo.m4 serial 5
-dnl Copyright (C) 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-2013 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.
diff --git a/gl/m4/off_t.m4 b/gl/m4/off_t.m4
index dfca2df..d355d01 100644
--- a/gl/m4/off_t.m4
+++ b/gl/m4/off_t.m4
@@ -1,5 +1,5 @@
 # off_t.m4 serial 1
-dnl Copyright (C) 2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2012-2013 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.
diff --git a/gl/m4/regex.m4 b/gl/m4/regex.m4
index 41be5e8..0945c11 100644
--- a/gl/m4/regex.m4
+++ b/gl/m4/regex.m4
@@ -1,6 +1,6 @@
-# serial 61
+# serial 64
 
-# Copyright (C) 1996-2001, 2003-2012 Free Software Foundation, Inc.
+# Copyright (C) 1996-2001, 2003-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -27,15 +27,21 @@ AC_DEFUN([gl_REGEX],
     # 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_CHECK_DECLS_ONCE([alarm])
     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>
-           ]],
+          [[#include <regex.h>
+
+            #include <locale.h>
+            #include <limits.h>
+            #include <string.h>
+            #if HAVE_DECL_ALARM
+            # include <unistd.h>
+            # include <signal.h>
+            #endif
+          ]],
           [[int result = 0;
             static struct re_pattern_buffer regex;
             unsigned char folded_chars[UCHAR_MAX + 1];
@@ -43,26 +49,65 @@ AC_DEFUN([gl_REGEX],
             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 HAVE_DECL_ALARM
+            /* Some builds of glibc go into an infinite loop on this test.  */
+            signal (SIGALRM, SIG_DFL);
+            alarm (2);
+#endif
             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;
+                {
+                  /* 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.  */
+                  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;
+                }
+
+                {
+                  /* This test is from glibc bug 15078.
+                     The test case is from Andreas Schwab in
+                     <http://www.sourceware.org/ml/libc-alpha/2013-01/msg00967.html>.
+                     */
+                  static char const pat[] = "[^x]x";
+                  static char const data[] =
+                    /* <U1000><U103B><U103D><U1014><U103A><U102F><U1015><U103A> */
+                    "\xe1\x80\x80"
+                    "\xe1\x80\xbb"
+                    "\xe1\x80\xbd"
+                    "\xe1\x80\x94"
+                    "\xe1\x80\xba"
+                    "\xe1\x80\xaf"
+                    "\xe1\x80\x95"
+                    "\xe1\x80\xba"
+                    "x";
+                  re_set_syntax (0);
+                  memset (&regex, 0, sizeof regex);
+                  s = re_compile_pattern (pat, sizeof pat - 1, &regex);
+                  if (s)
+                    result |= 1;
+                  else
+                    {
+                      i = re_search (&regex, data, sizeof data - 1,
+                                     0, sizeof data - 1, 0);
+                      if (i != 0 && i != 21)
+                        result |= 1;
+                    }
+                }
+
                 if (! setlocale (LC_ALL, "C"))
                   return 1;
               }
@@ -220,6 +265,8 @@ AC_DEFUN([gl_PREREQ_REGEX],
   AC_REQUIRE([AC_C_INLINE])
   AC_REQUIRE([AC_C_RESTRICT])
   AC_REQUIRE([AC_TYPE_MBSTATE_T])
+  AC_REQUIRE([gl_EEMALLOC])
+  AC_REQUIRE([gl_GLIBC21])
   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
index 209d64c..6338134 100644
--- a/gl/m4/ssize_t.m4
+++ b/gl/m4/ssize_t.m4
@@ -1,5 +1,5 @@
 # ssize_t.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2001-2003, 2006, 2010-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2001-2003, 2006, 2010-2013 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.
diff --git a/gl/m4/stdbool.m4 b/gl/m4/stdbool.m4
index eabfa64..80d5559 100644
--- a/gl/m4/stdbool.m4
+++ b/gl/m4/stdbool.m4
@@ -1,6 +1,6 @@
 # Check for stdbool.h that conforms to C99.
 
-dnl Copyright (C) 2002-2006, 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2006, 2009-2013 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.
diff --git a/gl/m4/stddef_h.m4 b/gl/m4/stddef_h.m4
index cc11609..5da8ab1 100644
--- a/gl/m4/stddef_h.m4
+++ b/gl/m4/stddef_h.m4
@@ -1,6 +1,6 @@
 dnl A placeholder for POSIX 2008 <stddef.h>, for platforms that have issues.
 # stddef_h.m4 serial 4
-dnl Copyright (C) 2009-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-2013 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.
diff --git a/gl/m4/stdint.m4 b/gl/m4/stdint.m4
index 28d342e..27cdcdb 100644
--- a/gl/m4/stdint.m4
+++ b/gl/m4/stdint.m4
@@ -1,5 +1,5 @@
 # stdint.m4 serial 43
-dnl Copyright (C) 2001-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2001-2013 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.
diff --git a/gl/m4/stdlib_h.m4 b/gl/m4/stdlib_h.m4
index ab43728..2027ab3 100644
--- a/gl/m4/stdlib_h.m4
+++ b/gl/m4/stdlib_h.m4
@@ -1,5 +1,5 @@
-# stdlib_h.m4 serial 41
-dnl Copyright (C) 2007-2012 Free Software Foundation, Inc.
+# stdlib_h.m4 serial 42
+dnl Copyright (C) 2007-2013 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.
@@ -22,7 +22,7 @@ AC_DEFUN([gl_STDLIB_H],
     ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt
     initstate initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps
     posix_openpt ptsname ptsname_r random random_r realpath rpmatch
-    setenv setstate setstate_r srandom srandom_r
+    secure_getenv setenv setstate setstate_r srandom srandom_r
     strtod strtoll strtoull unlockpt unsetenv])
 ])
 
@@ -60,6 +60,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX])
   GNULIB_REALPATH=0;      AC_SUBST([GNULIB_REALPATH])
   GNULIB_RPMATCH=0;       AC_SUBST([GNULIB_RPMATCH])
+  GNULIB_SECURE_GETENV=0; AC_SUBST([GNULIB_SECURE_GETENV])
   GNULIB_SETENV=0;        AC_SUBST([GNULIB_SETENV])
   GNULIB_STRTOD=0;        AC_SUBST([GNULIB_STRTOD])
   GNULIB_STRTOLL=0;       AC_SUBST([GNULIB_STRTOLL])
@@ -88,6 +89,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   HAVE_RANDOM_R=1;           AC_SUBST([HAVE_RANDOM_R])
   HAVE_REALPATH=1;           AC_SUBST([HAVE_REALPATH])
   HAVE_RPMATCH=1;            AC_SUBST([HAVE_RPMATCH])
+  HAVE_SECURE_GETENV=1;      AC_SUBST([HAVE_SECURE_GETENV])
   HAVE_SETENV=1;             AC_SUBST([HAVE_SETENV])
   HAVE_DECL_SETENV=1;        AC_SUBST([HAVE_DECL_SETENV])
   HAVE_STRTOD=1;             AC_SUBST([HAVE_STRTOD])
@@ -102,6 +104,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   REPLACE_MALLOC=0;          AC_SUBST([REPLACE_MALLOC])
   REPLACE_MBTOWC=0;          AC_SUBST([REPLACE_MBTOWC])
   REPLACE_MKSTEMP=0;         AC_SUBST([REPLACE_MKSTEMP])
+  REPLACE_PTSNAME=0;         AC_SUBST([REPLACE_PTSNAME])
   REPLACE_PTSNAME_R=0;       AC_SUBST([REPLACE_PTSNAME_R])
   REPLACE_PUTENV=0;          AC_SUBST([REPLACE_PUTENV])
   REPLACE_RANDOM_R=0;        AC_SUBST([REPLACE_RANDOM_R])
diff --git a/gl/m4/strcase.m4 b/gl/m4/strcase.m4
deleted file mode 100644
index 717fa9c..0000000
--- a/gl/m4/strcase.m4
+++ /dev/null
@@ -1,45 +0,0 @@
-# strcase.m4 serial 11
-dnl Copyright (C) 2002, 2005-2012 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_STRCASE],
-[
-  gl_FUNC_STRCASECMP
-  gl_FUNC_STRNCASECMP
-])
-
-AC_DEFUN([gl_FUNC_STRCASECMP],
-[
-  AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS])
-  AC_CHECK_FUNCS([strcasecmp])
-  if test $ac_cv_func_strcasecmp = no; then
-    HAVE_STRCASECMP=0
-  fi
-])
-
-AC_DEFUN([gl_FUNC_STRNCASECMP],
-[
-  AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS])
-  AC_CHECK_FUNCS([strncasecmp])
-  if test $ac_cv_func_strncasecmp = yes; then
-    HAVE_STRNCASECMP=1
-  else
-    HAVE_STRNCASECMP=0
-  fi
-  AC_CHECK_DECLS([strncasecmp])
-  if test $ac_cv_have_decl_strncasecmp = no; then
-    HAVE_DECL_STRNCASECMP=0
-  fi
-])
-
-# Prerequisites of lib/strcasecmp.c.
-AC_DEFUN([gl_PREREQ_STRCASECMP], [
-  :
-])
-
-# Prerequisites of lib/strncasecmp.c.
-AC_DEFUN([gl_PREREQ_STRNCASECMP], [
-  :
-])
diff --git a/gl/m4/strings_h.m4 b/gl/m4/strings_h.m4
deleted file mode 100644
index a057e1c..0000000
--- a/gl/m4/strings_h.m4
+++ /dev/null
@@ -1,52 +0,0 @@
-# Configure a replacement for <strings.h>.
-# serial 6
-
-# Copyright (C) 2007, 2009-2012 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.
-
-AC_DEFUN([gl_HEADER_STRINGS_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_HEADER_STRINGS_H_BODY])
-])
-
-AC_DEFUN([gl_HEADER_STRINGS_H_BODY],
-[
-  AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS])
-
-  gl_CHECK_NEXT_HEADERS([strings.h])
-  if test $ac_cv_header_strings_h = yes; then
-    HAVE_STRINGS_H=1
-  else
-    HAVE_STRINGS_H=0
-  fi
-  AC_SUBST([HAVE_STRINGS_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([[
-    /* Minix 3.1.8 has a bug: <sys/types.h> must be included before
-       <strings.h>.  */
-    #include <sys/types.h>
-    #include <strings.h>
-    ]], [ffs strcasecmp strncasecmp])
-])
-
-AC_DEFUN([gl_STRINGS_MODULE_INDICATOR],
-[
-  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
-  AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS])
-  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
-])
-
-AC_DEFUN([gl_HEADER_STRINGS_H_DEFAULTS],
-[
-  GNULIB_FFS=0;            AC_SUBST([GNULIB_FFS])
-  dnl Assume proper GNU behavior unless another module says otherwise.
-  HAVE_FFS=1;              AC_SUBST([HAVE_FFS])
-  HAVE_STRCASECMP=1;       AC_SUBST([HAVE_STRCASECMP])
-  HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP])
-])
diff --git a/gl/m4/sys_types_h.m4 b/gl/m4/sys_types_h.m4
index f11eef2..d15c1b3 100644
--- a/gl/m4/sys_types_h.m4
+++ b/gl/m4/sys_types_h.m4
@@ -1,10 +1,10 @@
-# sys_types_h.m4 serial 4
-dnl Copyright (C) 2011-2012 Free Software Foundation, Inc.
+# sys_types_h.m4 serial 5
+dnl Copyright (C) 2011-2013 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_SYS_TYPES_H],
+AC_DEFUN_ONCE([gl_SYS_TYPES_H],
 [
   AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS])
   gl_NEXT_HEADERS([sys/types.h])
diff --git a/gl/m4/threadlib.m4 b/gl/m4/threadlib.m4
new file mode 100644
index 0000000..26bdeb5
--- /dev/null
+++ b/gl/m4/threadlib.m4
@@ -0,0 +1,371 @@
+# threadlib.m4 serial 10 (gettext-0.18.2)
+dnl Copyright (C) 2005-2013 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 gl_THREADLIB
+dnl ------------
+dnl Tests for a multithreading library to be used.
+dnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO
+dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the
+dnl default is 'no', otherwise it is system dependent. In both cases, the user
+dnl can change the choice through the options --enable-threads=choice or
+dnl --disable-threads.
+dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS,
+dnl USE_PTH_THREADS, USE_WINDOWS_THREADS
+dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use
+dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with
+dnl libtool).
+dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for
+dnl programs that really need multithread functionality. The difference
+dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak
+dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread".
+dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for
+dnl multithread-safe programs.
+
+AC_DEFUN([gl_THREADLIB_EARLY],
+[
+  AC_REQUIRE([gl_THREADLIB_EARLY_BODY])
+])
+
+dnl The guts of gl_THREADLIB_EARLY. Needs to be expanded only once.
+
+AC_DEFUN([gl_THREADLIB_EARLY_BODY],
+[
+  dnl Ordering constraints: This macro modifies CPPFLAGS in a way that
+  dnl influences the result of the autoconf tests that test for *_unlocked
+  dnl declarations, on AIX 5 at least. Therefore it must come early.
+  AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl
+  AC_BEFORE([$0], [gl_ARGP])dnl
+
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems.
+  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])])
+  dnl Check for multithreading.
+  m4_ifdef([gl_THREADLIB_DEFAULT_NO],
+    [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])],
+    [m4_divert_text([DEFAULTS], [gl_use_threads_default=])])
+  AC_ARG_ENABLE([threads],
+AC_HELP_STRING([--enable-threads={posix|solaris|pth|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [
+AC_HELP_STRING([--disable-threads], [build without multithread safety])]),
+    [gl_use_threads=$enableval],
+    [if test -n "$gl_use_threads_default"; then
+       gl_use_threads="$gl_use_threads_default"
+     else
+changequote(,)dnl
+       case "$host_os" in
+         dnl Disable multithreading by default on OSF/1, because it interferes
+         dnl with fork()/exec(): When msgexec is linked with -lpthread, its
+         dnl child process gets an endless segmentation fault inside execvp().
+         dnl Disable multithreading by default on Cygwin 1.5.x, because it has
+         dnl bugs that lead to endless loops or crashes. See
+         dnl <http://cygwin.com/ml/cygwin/2009-08/msg00283.html>.
+         osf*) gl_use_threads=no ;;
+         cygwin*)
+               case `uname -r` in
+                 1.[0-5].*) gl_use_threads=no ;;
+                 *)         gl_use_threads=yes ;;
+               esac
+               ;;
+         *)    gl_use_threads=yes ;;
+       esac
+changequote([,])dnl
+     fi
+    ])
+  if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
+    # For using <pthread.h>:
+    case "$host_os" in
+      osf*)
+        # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
+        # groks <pthread.h>. cc also understands the flag -pthread, but
+        # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
+        # 2. putting a flag into CPPFLAGS that has an effect on the linker
+        # causes the AC_LINK_IFELSE test below to succeed unexpectedly,
+        # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
+        CPPFLAGS="$CPPFLAGS -D_REENTRANT"
+        ;;
+    esac
+    # Some systems optimize for single-threaded programs by default, and
+    # need special flags to disable these optimizations. For example, the
+    # definition of 'errno' in <errno.h>.
+    case "$host_os" in
+      aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;;
+      solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;;
+    esac
+  fi
+])
+
+dnl The guts of gl_THREADLIB. Needs to be expanded only once.
+
+AC_DEFUN([gl_THREADLIB_BODY],
+[
+  AC_REQUIRE([gl_THREADLIB_EARLY_BODY])
+  gl_threads_api=none
+  LIBTHREAD=
+  LTLIBTHREAD=
+  LIBMULTITHREAD=
+  LTLIBMULTITHREAD=
+  if test "$gl_use_threads" != no; then
+    dnl Check whether the compiler and linker support weak declarations.
+    AC_CACHE_CHECK([whether imported symbols can be declared weak],
+      [gl_cv_have_weak],
+      [gl_cv_have_weak=no
+       dnl First, test whether the compiler accepts it syntactically.
+       AC_LINK_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[extern void xyzzy ();
+#pragma weak xyzzy]],
+            [[xyzzy();]])],
+         [gl_cv_have_weak=maybe])
+       if test $gl_cv_have_weak = maybe; then
+         dnl Second, test whether it actually works. On Cygwin 1.7.2, with
+         dnl gcc 4.3, symbols declared weak always evaluate to the address 0.
+         AC_RUN_IFELSE(
+           [AC_LANG_SOURCE([[
+#include <stdio.h>
+#pragma weak fputs
+int main ()
+{
+  return (fputs == NULL);
+}]])],
+           [gl_cv_have_weak=yes],
+           [gl_cv_have_weak=no],
+           [dnl When cross-compiling, assume that only ELF platforms support
+            dnl weak symbols.
+            AC_EGREP_CPP([Extensible Linking Format],
+              [#ifdef __ELF__
+               Extensible Linking Format
+               #endif
+              ],
+              [gl_cv_have_weak="guessing yes"],
+              [gl_cv_have_weak="guessing no"])
+           ])
+       fi
+      ])
+    if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
+      # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
+      # it groks <pthread.h>. It's added above, in gl_THREADLIB_EARLY_BODY.
+      AC_CHECK_HEADER([pthread.h],
+        [gl_have_pthread_h=yes], [gl_have_pthread_h=no])
+      if test "$gl_have_pthread_h" = yes; then
+        # Other possible tests:
+        #   -lpthreads (FSU threads, PCthreads)
+        #   -lgthreads
+        gl_have_pthread=
+        # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
+        # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
+        # the second one only in libpthread, and lock.c needs it.
+        AC_LINK_IFELSE(
+          [AC_LANG_PROGRAM(
+             [[#include <pthread.h>]],
+             [[pthread_mutex_lock((pthread_mutex_t*)0);
+               pthread_mutexattr_init((pthread_mutexattr_t*)0);]])],
+          [gl_have_pthread=yes])
+        # Test for libpthread by looking for pthread_kill. (Not pthread_self,
+        # since it is defined as a macro on OSF/1.)
+        if test -n "$gl_have_pthread"; then
+          # The program links fine without libpthread. But it may actually
+          # need to link with libpthread in order to create multiple threads.
+          AC_CHECK_LIB([pthread], [pthread_kill],
+            [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
+             # On Solaris and HP-UX, most pthread functions exist also in libc.
+             # Therefore pthread_in_use() needs to actually try to create a
+             # thread: pthread_create from libc will fail, whereas
+             # pthread_create will actually create a thread.
+             case "$host_os" in
+               solaris* | hpux*)
+                 AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1],
+                   [Define if the pthread_in_use() detection is hard.])
+             esac
+            ])
+        else
+          # Some library is needed. Try libpthread and libc_r.
+          AC_CHECK_LIB([pthread], [pthread_kill],
+            [gl_have_pthread=yes
+             LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread
+             LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread])
+          if test -z "$gl_have_pthread"; then
+            # For FreeBSD 4.
+            AC_CHECK_LIB([c_r], [pthread_kill],
+              [gl_have_pthread=yes
+               LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r
+               LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r])
+          fi
+        fi
+        if test -n "$gl_have_pthread"; then
+          gl_threads_api=posix
+          AC_DEFINE([USE_POSIX_THREADS], [1],
+            [Define if the POSIX multithreading library can be used.])
+          if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
+            if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+              AC_DEFINE([USE_POSIX_THREADS_WEAK], [1],
+                [Define if references to the POSIX multithreading library should be made weak.])
+              LIBTHREAD=
+              LTLIBTHREAD=
+            fi
+          fi
+        fi
+      fi
+    fi
+    if test -z "$gl_have_pthread"; then
+      if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then
+        gl_have_solaristhread=
+        gl_save_LIBS="$LIBS"
+        LIBS="$LIBS -lthread"
+        AC_LINK_IFELSE(
+          [AC_LANG_PROGRAM(
+             [[
+#include <thread.h>
+#include <synch.h>
+             ]],
+             [[thr_self();]])],
+          [gl_have_solaristhread=yes])
+        LIBS="$gl_save_LIBS"
+        if test -n "$gl_have_solaristhread"; then
+          gl_threads_api=solaris
+          LIBTHREAD=-lthread
+          LTLIBTHREAD=-lthread
+          LIBMULTITHREAD="$LIBTHREAD"
+          LTLIBMULTITHREAD="$LTLIBTHREAD"
+          AC_DEFINE([USE_SOLARIS_THREADS], [1],
+            [Define if the old Solaris multithreading library can be used.])
+          if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+            AC_DEFINE([USE_SOLARIS_THREADS_WEAK], [1],
+              [Define if references to the old Solaris multithreading library should be made weak.])
+            LIBTHREAD=
+            LTLIBTHREAD=
+          fi
+        fi
+      fi
+    fi
+    if test "$gl_use_threads" = pth; then
+      gl_save_CPPFLAGS="$CPPFLAGS"
+      AC_LIB_LINKFLAGS([pth])
+      gl_have_pth=
+      gl_save_LIBS="$LIBS"
+      LIBS="$LIBS $LIBPTH"
+      AC_LINK_IFELSE(
+        [AC_LANG_PROGRAM([[#include <pth.h>]], [[pth_self();]])],
+        [gl_have_pth=yes])
+      LIBS="$gl_save_LIBS"
+      if test -n "$gl_have_pth"; then
+        gl_threads_api=pth
+        LIBTHREAD="$LIBPTH"
+        LTLIBTHREAD="$LTLIBPTH"
+        LIBMULTITHREAD="$LIBTHREAD"
+        LTLIBMULTITHREAD="$LTLIBTHREAD"
+        AC_DEFINE([USE_PTH_THREADS], [1],
+          [Define if the GNU Pth multithreading library can be used.])
+        if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
+          if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+            AC_DEFINE([USE_PTH_THREADS_WEAK], [1],
+              [Define if references to the GNU Pth multithreading library should be made weak.])
+            LIBTHREAD=
+            LTLIBTHREAD=
+          fi
+        fi
+      else
+        CPPFLAGS="$gl_save_CPPFLAGS"
+      fi
+    fi
+    if test -z "$gl_have_pthread"; then
+      case "$gl_use_threads" in
+        yes | windows | win32) # The 'win32' is for backward compatibility.
+          if { case "$host_os" in
+                 mingw*) true;;
+                 *) false;;
+               esac
+             }; then
+            gl_threads_api=windows
+            AC_DEFINE([USE_WINDOWS_THREADS], [1],
+              [Define if the native Windows multithreading API can be used.])
+          fi
+          ;;
+      esac
+    fi
+  fi
+  AC_MSG_CHECKING([for multithread API to use])
+  AC_MSG_RESULT([$gl_threads_api])
+  AC_SUBST([LIBTHREAD])
+  AC_SUBST([LTLIBTHREAD])
+  AC_SUBST([LIBMULTITHREAD])
+  AC_SUBST([LTLIBMULTITHREAD])
+])
+
+AC_DEFUN([gl_THREADLIB],
+[
+  AC_REQUIRE([gl_THREADLIB_EARLY])
+  AC_REQUIRE([gl_THREADLIB_BODY])
+])
+
+
+dnl gl_DISABLE_THREADS
+dnl ------------------
+dnl Sets the gl_THREADLIB default so that threads are not used by default.
+dnl The user can still override it at installation time, by using the
+dnl configure option '--enable-threads'.
+
+AC_DEFUN([gl_DISABLE_THREADS], [
+  m4_divert_text([INIT_PREPARE], [gl_use_threads_default=no])
+])
+
+
+dnl Survey of platforms:
+dnl
+dnl Platform           Available  Compiler    Supports   test-lock
+dnl                    flavours   option      weak       result
+dnl ---------------    ---------  ---------   --------   ---------
+dnl Linux 2.4/glibc    posix      -lpthread       Y      OK
+dnl
+dnl GNU Hurd/glibc     posix
+dnl
+dnl FreeBSD 5.3        posix      -lc_r           Y
+dnl                    posix      -lkse ?         Y
+dnl                    posix      -lpthread ?     Y
+dnl                    posix      -lthr           Y
+dnl
+dnl FreeBSD 5.2        posix      -lc_r           Y
+dnl                    posix      -lkse           Y
+dnl                    posix      -lthr           Y
+dnl
+dnl FreeBSD 4.0,4.10   posix      -lc_r           Y      OK
+dnl
+dnl NetBSD 1.6         --
+dnl
+dnl OpenBSD 3.4        posix      -lpthread       Y      OK
+dnl
+dnl Mac OS X 10.[123]  posix      -lpthread       Y      OK
+dnl
+dnl Solaris 7,8,9      posix      -lpthread       Y      Sol 7,8: 0.0; Sol 9: OK
+dnl                    solaris    -lthread        Y      Sol 7,8: 0.0; Sol 9: OK
+dnl
+dnl HP-UX 11           posix      -lpthread       N (cc) OK
+dnl                                               Y (gcc)
+dnl
+dnl IRIX 6.5           posix      -lpthread       Y      0.5
+dnl
+dnl AIX 4.3,5.1        posix      -lpthread       N      AIX 4: 0.5; AIX 5: OK
+dnl
+dnl OSF/1 4.0,5.1      posix      -pthread (cc)   N      OK
+dnl                               -lpthread (gcc) Y
+dnl
+dnl Cygwin             posix      -lpthread       Y      OK
+dnl
+dnl Any of the above   pth        -lpth                  0.0
+dnl
+dnl Mingw              windows                    N      OK
+dnl
+dnl BeOS 5             --
+dnl
+dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is
+dnl turned off:
+dnl   OK if all three tests terminate OK,
+dnl   0.5 if the first test terminates OK but the second one loops endlessly,
+dnl   0.0 if the first test already loops endlessly.
diff --git a/gl/m4/unistd_h.m4 b/gl/m4/unistd_h.m4
index 7e7651b..4231578 100644
--- a/gl/m4/unistd_h.m4
+++ b/gl/m4/unistd_h.m4
@@ -1,5 +1,5 @@
-# unistd_h.m4 serial 65
-dnl Copyright (C) 2006-2012 Free Software Foundation, Inc.
+# unistd_h.m4 serial 67
+dnl Copyright (C) 2006-2013 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.
@@ -11,7 +11,6 @@ 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
@@ -161,6 +160,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   REPLACE_FTRUNCATE=0;    AC_SUBST([REPLACE_FTRUNCATE])
   REPLACE_GETCWD=0;       AC_SUBST([REPLACE_GETCWD])
   REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME])
+  REPLACE_GETDTABLESIZE=0; AC_SUBST([REPLACE_GETDTABLESIZE])
   REPLACE_GETLOGIN_R=0;   AC_SUBST([REPLACE_GETLOGIN_R])
   REPLACE_GETGROUPS=0;    AC_SUBST([REPLACE_GETGROUPS])
   REPLACE_GETPAGESIZE=0;  AC_SUBST([REPLACE_GETPAGESIZE])
diff --git a/gl/m4/warn-on-use.m4 b/gl/m4/warn-on-use.m4
index a77802e..e43beeb 100644
--- a/gl/m4/warn-on-use.m4
+++ b/gl/m4/warn-on-use.m4
@@ -1,5 +1,5 @@
 # warn-on-use.m4 serial 5
-dnl Copyright (C) 2010-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2010-2013 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.
diff --git a/gl/m4/wchar_h.m4 b/gl/m4/wchar_h.m4
index c7a8b2d..bedb15a 100644
--- a/gl/m4/wchar_h.m4
+++ b/gl/m4/wchar_h.m4
@@ -1,6 +1,6 @@
 dnl A placeholder for ISO C99 <wchar.h>, for platforms that have issues.
 
-dnl Copyright (C) 2007-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-2013 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.
diff --git a/gl/m4/wchar_t.m4 b/gl/m4/wchar_t.m4
index 534735d..e1e1e69 100644
--- a/gl/m4/wchar_t.m4
+++ b/gl/m4/wchar_t.m4
@@ -1,5 +1,5 @@
 # wchar_t.m4 serial 4 (gettext-0.18.2)
-dnl Copyright (C) 2002-2003, 2008-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2003, 2008-2013 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.
diff --git a/gl/m4/wcrtomb.m4 b/gl/m4/wcrtomb.m4
index 00d7302..f56b5ba 100644
--- a/gl/m4/wcrtomb.m4
+++ b/gl/m4/wcrtomb.m4
@@ -1,5 +1,5 @@
 # wcrtomb.m4 serial 11
-dnl Copyright (C) 2008-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-2013 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.
diff --git a/gl/m4/wctype_h.m4 b/gl/m4/wctype_h.m4
index 4b19f64..82ada0e 100644
--- a/gl/m4/wctype_h.m4
+++ b/gl/m4/wctype_h.m4
@@ -1,8 +1,8 @@
-# wctype_h.m4 serial 17
+# wctype_h.m4 serial 18
 
 dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it.
 
-dnl Copyright (C) 2006-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2006-2013 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.
@@ -22,8 +22,6 @@ AC_DEFUN([gl_WCTYPE_H],
   fi
   AC_SUBST([HAVE_ISWCNTRL])
 
-  AC_REQUIRE([AC_C_INLINE])
-
   AC_REQUIRE([gt_TYPE_WINT_T])
   if test $gt_cv_c_wint_t = yes; then
     HAVE_WINT_T=1
diff --git a/gl/m4/wint_t.m4 b/gl/m4/wint_t.m4
index 3260cce..d7cd3db 100644
--- a/gl/m4/wint_t.m4
+++ b/gl/m4/wint_t.m4
@@ -1,5 +1,5 @@
 # wint_t.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2003, 2007-2012 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2007-2013 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.
diff --git a/gl/malloc.c b/gl/malloc.c
index 109c65c..8124cad 100644
--- a/gl/malloc.c
+++ b/gl/malloc.c
@@ -1,6 +1,6 @@
 /* malloc() function that is glibc compatible.
 
-   Copyright (C) 1997-1998, 2006-2007, 2009-2012 Free Software Foundation, Inc.
+   Copyright (C) 1997-1998, 2006-2007, 2009-2013 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
diff --git a/gl/mbrtowc.c b/gl/mbrtowc.c
index 5f2ec07..75d10bc 100644
--- a/gl/mbrtowc.c
+++ b/gl/mbrtowc.c
@@ -1,5 +1,5 @@
 /* Convert multibyte character to wide character.
-   Copyright (C) 1999-2002, 2005-2012 Free Software Foundation, Inc.
+   Copyright (C) 1999-2002, 2005-2013 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
diff --git a/gl/mbsinit.c b/gl/mbsinit.c
index 79278d4..98ae1e6 100644
--- a/gl/mbsinit.c
+++ b/gl/mbsinit.c
@@ -1,5 +1,5 @@
 /* Test for initial conversion state.
-   Copyright (C) 2008-2012 Free Software Foundation, Inc.
+   Copyright (C) 2008-2013 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
diff --git a/gl/mbtowc-impl.h b/gl/mbtowc-impl.h
index 3183f91..35b3528 100644
--- a/gl/mbtowc-impl.h
+++ b/gl/mbtowc-impl.h
@@ -1,5 +1,5 @@
 /* Convert multibyte character to wide character.
-   Copyright (C) 2011-2012 Free Software Foundation, Inc.
+   Copyright (C) 2011-2013 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno at clisp.org>, 2011.
 
    This program is free software: you can redistribute it and/or modify
diff --git a/gl/mbtowc.c b/gl/mbtowc.c
index e48b2f2..7777f0a 100644
--- a/gl/mbtowc.c
+++ b/gl/mbtowc.c
@@ -1,5 +1,5 @@
 /* Convert multibyte character to wide character.
-   Copyright (C) 2011-2012 Free Software Foundation, Inc.
+   Copyright (C) 2011-2013 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno at clisp.org>, 2011.
 
    This program is free software: you can redistribute it and/or modify
diff --git a/gl/nl_langinfo.c b/gl/nl_langinfo.c
index 4b9bdbe..2210b7f 100644
--- a/gl/nl_langinfo.c
+++ b/gl/nl_langinfo.c
@@ -1,6 +1,6 @@
 /* nl_langinfo() replacement: query locale dependent information.
 
-   Copyright (C) 2007-2012 Free Software Foundation, Inc.
+   Copyright (C) 2007-2013 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
diff --git a/gl/ref-add.sin b/gl/ref-add.sin
index 8c1a7d0..7cbdec5 100644
--- a/gl/ref-add.sin
+++ b/gl/ref-add.sin
@@ -1,6 +1,6 @@
 # Add this package to a list of references stored in a text file.
 #
-#   Copyright (C) 2000, 2009-2012 Free Software Foundation, Inc.
+#   Copyright (C) 2000, 2009-2013 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
diff --git a/gl/ref-del.sin b/gl/ref-del.sin
index fd87588..cf7b492 100644
--- a/gl/ref-del.sin
+++ b/gl/ref-del.sin
@@ -1,6 +1,6 @@
 # Remove this package from a list of references stored in a text file.
 #
-#   Copyright (C) 2000, 2009-2012 Free Software Foundation, Inc.
+#   Copyright (C) 2000, 2009-2013 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
diff --git a/gl/regcomp.c b/gl/regcomp.c
index 1bd1924..4de2ed2 100644
--- a/gl/regcomp.c
+++ b/gl/regcomp.c
@@ -1,20 +1,21 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2012 Free Software Foundation, Inc.
+   Copyright (C) 2002-2013 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.
+   The GNU C 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 program is distributed in the hope that it will be useful,
+   The GNU C 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.
+   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/>.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
 					  size_t length, reg_syntax_t syntax);
@@ -93,20 +94,20 @@ 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,
+				      const 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,
+				      const 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,
+				       const char *class_name,
+				       const 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,
@@ -291,7 +292,7 @@ weak_alias (__re_compile_fastmap, re_compile_fastmap)
 #endif
 
 static inline void
-__attribute ((always_inline))
+__attribute__ ((always_inline))
 re_set_fastmap (char *fastmap, bool icase, int ch)
 {
   fastmap[ch] = 1;
@@ -585,7 +586,7 @@ weak_alias (__regerror, regerror)
 static const bitset_t utf8_sb_map =
 {
   /* Set the first 128 bits.  */
-# ifdef __GNUC__
+# if defined __GNUC__ && !defined __STRICT_ANSI__
   [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX
 # else
 #  if 4 * BITSET_WORD_BITS < ASCII_CHARS
@@ -662,7 +663,10 @@ regfree (preg)
 {
   re_dfa_t *dfa = preg->buffer;
   if (BE (dfa != NULL, 1))
-    free_dfa_content (dfa);
+    {
+      lock_fini (dfa->lock);
+      free_dfa_content (dfa);
+    }
   preg->buffer = NULL;
   preg->allocated = 0;
 
@@ -783,6 +787,8 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
   preg->used = sizeof (re_dfa_t);
 
   err = init_dfa (dfa, length);
+  if (BE (err == REG_NOERROR && lock_init (dfa->lock) != 0, 0))
+    err = REG_ESPACE;
   if (BE (err != REG_NOERROR, 0))
     {
       free_dfa_content (dfa);
@@ -796,8 +802,6 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
   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))
@@ -805,6 +809,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
     re_compile_internal_free_return:
       free_workarea_compile (preg);
       re_string_destruct (&regexp);
+      lock_fini (dfa->lock);
       free_dfa_content (dfa);
       preg->buffer = NULL;
       preg->allocated = 0;
@@ -837,6 +842,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
 
   if (BE (err != REG_NOERROR, 0))
     {
+      lock_fini (dfa->lock);
       free_dfa_content (dfa);
       preg->buffer = NULL;
       preg->allocated = 0;
@@ -899,8 +905,10 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
 		       != 0);
 #else
   codeset_name = nl_langinfo (CODESET);
-  if (strcasecmp (codeset_name, "UTF-8") == 0
-      || strcasecmp (codeset_name, "UTF8") == 0)
+  if ((codeset_name[0] == 'U' || codeset_name[0] == 'u')
+      && (codeset_name[1] == 'T' || codeset_name[1] == 't')
+      && (codeset_name[2] == 'F' || codeset_name[2] == 'f')
+      && strcmp (codeset_name + 3 + (codeset_name[3] == '-'), "8") == 0)
     dfa->is_utf8 = 1;
 
   /* We check exhaustively in the loop below if this charset is a
@@ -950,10 +958,10 @@ static void
 internal_function
 init_word_char (re_dfa_t *dfa)
 {
-  dfa->word_ops_used = 1;
   int i = 0;
   int j;
   int ch = 0;
+  dfa->word_ops_used = 1;
   if (BE (dfa->map_notascii == 0, 1))
     {
       bitset_word_t bits0 = 0x00000000;
@@ -2419,8 +2427,8 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
     case OP_WORD:
     case OP_NOTWORD:
       tree = build_charclass_op (dfa, regexp->trans,
-				 (const unsigned char *) "alnum",
-				 (const unsigned char *) "_",
+				 "alnum",
+				 "_",
 				 token->type == OP_NOTWORD, err);
       if (BE (*err != REG_NOERROR && tree == NULL, 0))
 	return NULL;
@@ -2428,8 +2436,8 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
     case OP_SPACE:
     case OP_NOTSPACE:
       tree = build_charclass_op (dfa, regexp->trans,
-				 (const unsigned char *) "space",
-				 (const unsigned char *) "",
+				 "space",
+				 "",
 				 token->type == OP_NOTSPACE, err);
       if (BE (*err != REG_NOERROR && tree == NULL, 0))
 	return NULL;
@@ -2709,7 +2717,6 @@ build_range_exp (const reg_syntax_t syntax,
     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]
@@ -2723,11 +2730,7 @@ build_range_exp (const reg_syntax_t syntax,
 	      ? __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))
+    else if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_wc > end_wc, 0))
       return REG_ERANGE;
 
     /* Got valid collation sequence values, add them as a new entry.
@@ -2768,9 +2771,7 @@ build_range_exp (const reg_syntax_t syntax,
     /* 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)
+	if (start_wc <= wc && wc <= end_wc)
 	  bitset_set (sbcset, wc);
       }
   }
@@ -2839,40 +2840,29 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 
   /* Local function for parse_bracket_exp used in _LIBC environment.
      Seek the collating symbol entry corresponding to NAME.
-     Return the index of the symbol in the SYMB_TABLE.  */
+     Return the index of the symbol in the SYMB_TABLE,
+     or -1 if not found.  */
 
   auto inline int32_t
-  __attribute ((always_inline))
-  seek_collating_symbol_entry (name, name_len)
-	 const unsigned char *name;
-	 size_t name_len;
+  __attribute__ ((always_inline))
+  seek_collating_symbol_entry (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;
+      int32_t elem;
 
-	  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;
+      for (elem = 0; elem < table_size; elem++)
+	if (symb_table[2 * elem] != 0)
+	  {
+	    int32_t idx = symb_table[2 * elem + 1];
+	    /* Skip the name of collating element name.  */
+	    idx += 1 + extra[idx];
+	    if (/* Compare the length of the name.  */
+		name_len == extra[idx]
+		/* Compare the name.  */
+		&& memcmp (name, &extra[idx + 1], name_len) == 0)
+	      /* Yep, this is the entry.  */
+	      return elem;
+	  }
+      return -1;
     }
 
   /* Local function for parse_bracket_exp used in _LIBC environment.
@@ -2880,9 +2870,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
      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;
+  __attribute__ ((always_inline))
+  lookup_collation_sequence_value (bracket_elem_t *br_elem)
     {
       if (br_elem->type == SB_CHAR)
 	{
@@ -2910,7 +2899,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 	      int32_t elem, idx;
 	      elem = seek_collating_symbol_entry (br_elem->opr.name,
 						  sym_name_len);
-	      if (symb_table[2 * elem] != 0)
+	      if (elem != -1)
 		{
 		  /* We found the entry.  */
 		  idx = symb_table[2 * elem + 1];
@@ -2928,7 +2917,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 		  /* Return the collation sequence value.  */
 		  return *(unsigned int *) (extra + idx);
 		}
-	      else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
+	      else if (sym_name_len == 1)
 		{
 		  /* No valid character.  Match it as a single byte
 		     character.  */
@@ -2949,12 +2938,9 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
      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;
+  __attribute__ ((always_inline))
+  build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,
+		   bracket_elem_t *start_elem, bracket_elem_t *end_elem)
     {
       unsigned int ch;
       uint32_t start_collseq;
@@ -2967,6 +2953,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 	      0))
 	return REG_ERANGE;
 
+      /* FIXME: Implement rational ranges here, too.  */
       start_collseq = lookup_collation_sequence_value (start_elem);
       end_collseq = lookup_collation_sequence_value (end_elem);
       /* Check start/end collation sequence values.  */
@@ -3032,26 +3019,23 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
      pointer argument since 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;
+  __attribute__ ((always_inline))
+  build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
+			  Idx *coll_sym_alloc, 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)
+	  if (elem != -1)
 	    {
 	      /* 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)
+	  else if (name_len == 1)
 	    {
 	      /* No valid character, treat it as a normal
 		 character.  */
@@ -3294,7 +3278,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 #ifdef RE_ENABLE_I18N
 				      mbcset, &char_class_alloc,
 #endif /* RE_ENABLE_I18N */
-				      start_elem.opr.name, syntax);
+				      (const char *) start_elem.opr.name,
+				      syntax);
 	      if (BE (*err != REG_NOERROR, 0))
 	       goto parse_bracket_exp_free_return;
 	      break;
@@ -3574,14 +3559,14 @@ 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)
+		 const 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)
+		 const char *class_name, reg_syntax_t syntax)
 #endif /* not RE_ENABLE_I18N */
 {
   int i;
-  const char *name = (const char *) class_name;
+  const char *name = class_name;
 
   /* In case of REG_ICASE "upper" and "lower" match the both of
      upper and lower cases.  */
@@ -3655,8 +3640,8 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
 
 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,
+		    const char *class_name,
+		    const char *extra, bool non_match,
 		    reg_errcode_t *err)
 {
   re_bitset_ptr_t sbcset;
diff --git a/gl/regex.c b/gl/regex.c
index c578852..361f763 100644
--- a/gl/regex.c
+++ b/gl/regex.c
@@ -1,20 +1,21 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2003, 2005-2006, 2009-2012 Free Software Foundation, Inc.
+   Copyright (C) 2002-2013 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.
+   The GNU C 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 program is distributed in the hope that it will be useful,
+   The GNU C 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.
+   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/>.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #ifndef _LIBC
 # include <config.h>
@@ -23,6 +24,7 @@
 #  pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
 # endif
 # if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
+#  pragma GCC diagnostic ignored "-Wold-style-definition"
 #  pragma GCC diagnostic ignored "-Wtype-limits"
 # endif
 #endif
diff --git a/gl/regex.h b/gl/regex.h
index 07c1b3d..74645ca 100644
--- a/gl/regex.h
+++ b/gl/regex.h
@@ -1,21 +1,22 @@
 /* Definitions for data structures and routines for the regular
    expression library.
-   Copyright (C) 1985, 1989-1993, 1995-1998, 2000-2003, 2005-2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1985, 1989-1993, 1995-1998, 2000-2003, 2005-2013 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.
+   The GNU C 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 program is distributed in the hope that it will be useful,
+   The GNU C 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.
+   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/>.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #ifndef _REGEX_H
 #define _REGEX_H 1
diff --git a/gl/regex_internal.c b/gl/regex_internal.c
index 71ee41e..f679f87 100644
--- a/gl/regex_internal.c
+++ b/gl/regex_internal.c
@@ -1,20 +1,21 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2012 Free Software Foundation, Inc.
+   Copyright (C) 2002-2013 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.
+   The GNU C 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 program is distributed in the hope that it will be useful,
+   The GNU C 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.
+   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/>.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 static void re_string_construct_common (const char *str, Idx len,
 					re_string_t *pstr,
@@ -833,7 +834,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
 }
 
 static unsigned char
-internal_function __attribute ((pure))
+internal_function __attribute__ ((pure))
 re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
 {
   int ch;
@@ -973,7 +974,7 @@ 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))
+  if (BE (set->elems == NULL, 0) && (MALLOC_0_IS_NONNULL || size != 0))
     return REG_ESPACE;
   return REG_NOERROR;
 }
@@ -1353,7 +1354,7 @@ re_node_set_insert_last (re_node_set *set, Idx elem)
    Return true if SET1 and SET2 are equivalent.  */
 
 static bool
-internal_function __attribute ((pure))
+internal_function __attribute__ ((pure))
 re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
 {
   Idx i;
@@ -1368,7 +1369,7 @@ re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
 /* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
 
 static Idx
-internal_function __attribute ((pure))
+internal_function __attribute__ ((pure))
 re_node_set_contains (const re_node_set *set, Idx elem)
 {
   __re_size_t idx, right, mid;
@@ -1442,11 +1443,9 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
   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;
-  }
+    ((token.type == OP_PERIOD && dfa->mb_cur_max > 1)
+     || token.type == COMPLEX_BRACKET);
 #endif
   dfa->nexts[dfa->nodes_len] = REG_MISSING;
   re_node_set_init_empty (dfa->edests + dfa->nodes_len);
@@ -1454,7 +1453,7 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
   return dfa->nodes_len++;
 }
 
-static inline re_hashval_t
+static re_hashval_t
 internal_function
 calc_state_hash (const re_node_set *nodes, unsigned int context)
 {
diff --git a/gl/regex_internal.h b/gl/regex_internal.h
index fd331b1..0d19f35 100644
--- a/gl/regex_internal.h
+++ b/gl/regex_internal.h
@@ -1,20 +1,21 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2012 Free Software Foundation, Inc.
+   Copyright (C) 2002-2013 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.
+   The GNU C 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 program is distributed in the hope that it will be useful,
+   The GNU C 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.
+   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/>.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #ifndef _REGEX_INTERNAL_H
 #define _REGEX_INTERNAL_H 1
@@ -26,21 +27,55 @@
 #include <string.h>
 
 #include <langinfo.h>
-#ifndef _LIBC
-# include "localcharset.h"
-#endif
 #include <locale.h>
 #include <wchar.h>
 #include <wctype.h>
 #include <stdbool.h>
 #include <stdint.h>
-#if defined _LIBC
+
+#ifdef _LIBC
 # include <bits/libc-lock.h>
+# define lock_define(name) __libc_lock_define (, name)
+# define lock_init(lock) (__libc_lock_init (lock), 0)
+# define lock_fini(lock) 0
+# define lock_lock(lock) __libc_lock_lock (lock)
+# define lock_unlock(lock) __libc_lock_unlock (lock)
+#elif defined GNULIB_LOCK
+# include "glthread/lock.h"
+  /* Use gl_lock_define if empty macro arguments are known to work.
+     Otherwise, fall back on less-portable substitutes.  */
+# if ((defined __GNUC__ && !defined __STRICT_ANSI__) \
+      || (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__))
+#  define lock_define(name) gl_lock_define (, name)
+# elif USE_POSIX_THREADS
+#  define lock_define(name) pthread_mutex_t name;
+# elif USE_PTH_THREADS
+#  define lock_define(name) pth_mutex_t name;
+# elif USE_SOLARIS_THREADS
+#  define lock_define(name) mutex_t name;
+# elif USE_WINDOWS_THREADS
+#  define lock_define(name) gl_lock_t name;
+# else
+#  define lock_define(name)
+# endif
+# define lock_init(lock) glthread_lock_init (&(lock))
+# define lock_fini(lock) glthread_lock_destroy (&(lock))
+# define lock_lock(lock) glthread_lock_lock (&(lock))
+# define lock_unlock(lock) glthread_lock_unlock (&(lock))
+#elif defined GNULIB_PTHREAD
+# include <pthread.h>
+# define lock_define(name) pthread_mutex_t name;
+# define lock_init(lock) pthread_mutex_init (&(lock), 0)
+# define lock_fini(lock) pthread_mutex_destroy (&(lock))
+# define lock_lock(lock) pthread_mutex_lock (&(lock))
+# define lock_unlock(lock) pthread_mutex_unlock (&(lock))
 #else
-# define __libc_lock_define(CLASS,NAME)
-# define __libc_lock_init(NAME) do { } while (0)
-# define __libc_lock_lock(NAME) do { } while (0)
-# define __libc_lock_unlock(NAME) do { } while (0)
+# define lock_define(name)
+# define lock_init(lock) 0
+# define lock_fini(lock) ((void) 0)
+  /* The 'dfa' avoids an "unused variable 'dfa'" warning from GCC.  */
+# define lock_lock(lock) ((void) dfa)
+# define lock_unlock(lock) ((void) 0)
 #endif
 
 /* In case that the system doesn't have isblank().  */
@@ -63,7 +98,7 @@
 # ifdef _LIBC
 #  undef gettext
 #  define gettext(msgid) \
-  INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
+  __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES)
 # endif
 #else
 # define gettext(msgid) (msgid)
@@ -83,9 +118,6 @@
 # define BE(expr, val) __builtin_expect (expr, val)
 #else
 # define BE(expr, val) (expr)
-# ifdef _LIBC
-#  define inline
-# endif
 #endif
 
 /* Number of ASCII characters.  */
@@ -102,6 +134,8 @@
 
 /* Rename to standard API for using out of glibc.  */
 #ifndef _LIBC
+# undef __wctype
+# undef __iswctype
 # define __wctype wctype
 # define __iswctype iswctype
 # define __btowc btowc
@@ -111,10 +145,8 @@
 # define attribute_hidden
 #endif /* not _LIBC */
 
-#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
-# define __attribute(arg) __attribute__ (arg)
-#else
-# define __attribute(arg)
+#if __GNUC__ < 3 + (__GNUC_MINOR__ < 1)
+# define __attribute__(arg)
 #endif
 
 typedef __re_idx_t Idx;
@@ -430,7 +462,7 @@ 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));
+     internal_function __attribute__ ((pure));
 #endif
 #define re_string_peek_byte(pstr, offset) \
   ((pstr)->mbs[(pstr)->cur_idx + offset])
@@ -449,7 +481,9 @@ static unsigned int re_string_context_at (const re_string_t *input, Idx 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>
+#if defined _LIBC || HAVE_ALLOCA
+# include <alloca.h>
+#endif
 
 #ifndef _LIBC
 # if HAVE_ALLOCA
@@ -466,6 +500,12 @@ static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
 # endif
 #endif
 
+#ifdef _LIBC
+# define MALLOC_0_IS_NONNULL 1
+#elif !defined MALLOC_0_IS_NONNULL
+# define MALLOC_0_IS_NONNULL 0
+#endif
+
 #ifndef MAX
 # define MAX(a,b) ((a) < (b) ? (b) : (a))
 #endif
@@ -696,7 +736,7 @@ struct re_dfa_t
 #ifdef DEBUG
   char* re_str;
 #endif
-  __libc_lock_define (, lock)
+  lock_define (lock)
 };
 
 #define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
@@ -727,33 +767,33 @@ typedef struct
 } bracket_elem_t;
 
 
-/* Inline functions for bitset_t operation.  */
+/* Functions for bitset_t operation.  */
 
-static inline void
+static void
 bitset_set (bitset_t set, Idx i)
 {
   set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS;
 }
 
-static inline void
+static void
 bitset_clear (bitset_t set, Idx i)
 {
   set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS);
 }
 
-static inline bool
+static bool
 bitset_contain (const bitset_t set, Idx i)
 {
   return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1;
 }
 
-static inline void
+static void
 bitset_empty (bitset_t set)
 {
   memset (set, '\0', sizeof (bitset_t));
 }
 
-static inline void
+static void
 bitset_set_all (bitset_t set)
 {
   memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS));
@@ -762,13 +802,13 @@ bitset_set_all (bitset_t set)
       ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1;
 }
 
-static inline void
+static void
 bitset_copy (bitset_t dest, const bitset_t src)
 {
   memcpy (dest, src, sizeof (bitset_t));
 }
 
-static inline void
+static void __attribute__ ((unused))
 bitset_not (bitset_t set)
 {
   int bitset_i;
@@ -780,7 +820,7 @@ bitset_not (bitset_t set)
        & ~set[BITSET_WORDS - 1]);
 }
 
-static inline void
+static void __attribute__ ((unused))
 bitset_merge (bitset_t dest, const bitset_t src)
 {
   int bitset_i;
@@ -788,7 +828,7 @@ bitset_merge (bitset_t dest, const bitset_t src)
     dest[bitset_i] |= src[bitset_i];
 }
 
-static inline void
+static void __attribute__ ((unused))
 bitset_mask (bitset_t dest, const bitset_t src)
 {
   int bitset_i;
@@ -797,9 +837,9 @@ bitset_mask (bitset_t dest, const bitset_t src)
 }
 
 #ifdef RE_ENABLE_I18N
-/* Inline functions for re_string.  */
-static inline int
-internal_function __attribute ((pure))
+/* Functions for re_string.  */
+static int
+internal_function __attribute__ ((pure, unused))
 re_string_char_size_at (const re_string_t *pstr, Idx idx)
 {
   int byte_idx;
@@ -811,8 +851,8 @@ re_string_char_size_at (const re_string_t *pstr, Idx idx)
   return byte_idx;
 }
 
-static inline wint_t
-internal_function __attribute ((pure))
+static wint_t
+internal_function __attribute__ ((pure, unused))
 re_string_wchar_at (const re_string_t *pstr, Idx idx)
 {
   if (pstr->mb_cur_max == 1)
@@ -822,7 +862,7 @@ re_string_wchar_at (const re_string_t *pstr, Idx idx)
 
 # ifndef NOT_IN_libc
 static int
-internal_function __attribute ((pure))
+internal_function __attribute__ ((pure, unused))
 re_string_elem_size_at (const re_string_t *pstr, Idx idx)
 {
 #  ifdef _LIBC
diff --git a/gl/regexec.c b/gl/regexec.c
index b2c174f..21d14ad 100644
--- a/gl/regexec.c
+++ b/gl/regexec.c
@@ -1,20 +1,21 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2012 Free Software Foundation, Inc.
+   Copyright (C) 2002-2013 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.
+   The GNU C 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 program is distributed in the hope that it will be useful,
+   The GNU C 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.
+   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/>.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
 				     Idx n) internal_function;
@@ -198,7 +199,7 @@ static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa,
 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)
+static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len)
      internal_function;
 

 /* Entry point for POSIX code.  */
@@ -227,9 +228,7 @@ regexec (preg, string, nmatch, pmatch, eflags)
 {
   reg_errcode_t err;
   Idx start, length;
-#ifdef _LIBC
   re_dfa_t *dfa = preg->buffer;
-#endif
 
   if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
     return REG_BADPAT;
@@ -245,14 +244,14 @@ regexec (preg, string, nmatch, pmatch, eflags)
       length = strlen (string);
     }
 
-  __libc_lock_lock (dfa->lock);
+  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);
+  lock_unlock (dfa->lock);
   return err != REG_NOERROR;
 }
 
@@ -420,9 +419,7 @@ re_search_stub (struct re_pattern_buffer *bufp,
   Idx nregs;
   regoff_t rval;
   int eflags = 0;
-#ifdef _LIBC
   re_dfa_t *dfa = bufp->buffer;
-#endif
   Idx last_start = start + range;
 
   /* Check for out-of-range.  */
@@ -433,7 +430,7 @@ re_search_stub (struct re_pattern_buffer *bufp,
   else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0))
     last_start = 0;
 
-  __libc_lock_lock (dfa->lock);
+  lock_lock (dfa->lock);
 
   eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
   eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
@@ -497,7 +494,7 @@ re_search_stub (struct re_pattern_buffer *bufp,
     }
   re_free (pmatch);
  out:
-  __libc_lock_unlock (dfa->lock);
+  lock_unlock (dfa->lock);
   return rval;
 }
 
@@ -735,7 +732,7 @@ re_search_internal (const regex_t *preg,
   mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
 			   : CONTEXT_NEWLINE | CONTEXT_BEGBUF;
 
-  /* Check incrementally whether of not the input string match.  */
+  /* Check incrementally whether the input string matches.  */
   incr = (last_start < start) ? -1 : 1;
   left_lim = (last_start < start) ? last_start : start;
   right_lim = (last_start < start) ? start : last_start;
@@ -1063,7 +1060,7 @@ prune_impossible_nodes (re_match_context_t *mctx)
    since initial states may have constraints like "\<", "^", etc..  */
 
 static inline re_dfastate_t *
-__attribute ((always_inline)) internal_function
+__attribute__ ((always_inline)) internal_function
 acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
 			    Idx idx)
 {
@@ -1175,7 +1172,7 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match,
 	  || (BE (next_char_idx >= mctx->input.valid_len, 0)
 	      && mctx->input.valid_len < mctx->input.len))
 	{
-	  err = extend_buffers (mctx);
+	  err = extend_buffers (mctx, next_char_idx + 1);
 	  if (BE (err != REG_NOERROR, 0))
 	    {
 	      assert (err == REG_ESPACE);
@@ -1755,7 +1752,7 @@ clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx)
 	  && mctx->input.valid_len < mctx->input.len))
     {
       reg_errcode_t err;
-      err = extend_buffers (mctx);
+      err = extend_buffers (mctx, next_state_log_idx + 1);
       if (BE (err != REG_NOERROR, 0))
 	return err;
     }
@@ -2812,7 +2809,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx)
 		  if (bkref_str_off >= mctx->input.len)
 		    break;
 
-		  err = extend_buffers (mctx);
+		  err = extend_buffers (mctx, bkref_str_off + 1);
 		  if (BE (err != REG_NOERROR, 0))
 		    return err;
 
@@ -3935,6 +3932,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
 		in_collseq = find_collation_sequence_value (pin, elem_len);
 	    }
 	  /* match with range expression?  */
+	  /* FIXME: Implement rational ranges here, too.  */
 	  for (i = 0; i < cset->nranges; ++i)
 	    if (cset->range_starts[i] <= in_collseq
 		&& in_collseq <= cset->range_ends[i])
@@ -3986,18 +3984,9 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
 # endif /* _LIBC */
 	{
 	  /* match with range expression?  */
-#if __GNUC__ >= 2 && ! (__STDC_VERSION__ < 199901L && defined __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)
+	      if (cset->range_starts[i] <= wc && wc <= cset->range_ends[i])
 		{
 		  match_len = char_len;
 		  goto check_node_accept_bytes_match;
@@ -4135,7 +4124,7 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
 
 static reg_errcode_t
 internal_function __attribute_warn_unused_result__
-extend_buffers (re_match_context_t *mctx)
+extend_buffers (re_match_context_t *mctx, int min_len)
 {
   reg_errcode_t ret;
   re_string_t *pstr = &mctx->input;
@@ -4145,8 +4134,10 @@ extend_buffers (re_match_context_t *mctx)
           <= pstr->bufs_len, 0))
     return REG_ESPACE;
 
-  /* Double the lengths of the buffers.  */
-  ret = re_string_realloc_buffers (pstr, MIN (pstr->len, pstr->bufs_len * 2));
+  /* Double the lengths of the buffers, but allocate at least MIN_LEN.  */
+  ret = re_string_realloc_buffers (pstr,
+				   MAX (min_len,
+					MIN (pstr->len, pstr->bufs_len * 2)));
   if (BE (ret != REG_NOERROR, 0))
     return ret;
 
diff --git a/gl/stdbool.in.h b/gl/stdbool.in.h
index 6ea7f70..bd629ed 100644
--- a/gl/stdbool.in.h
+++ b/gl/stdbool.in.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2003, 2006-2012 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2003, 2006-2013 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
@@ -66,24 +66,19 @@
 # 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__)
+#ifdef __cplusplus
+# define _Bool bool
+# define bool bool
+#else
+# if 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@
+#  if !@HAVE__BOOL@
 typedef bool _Bool;
-# endif
-#else
-# if !defined __GNUC__
+#  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
@@ -103,19 +98,35 @@ typedef bool _Bool;
           "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
+#   define _Bool signed char
+#  else
    /* With this compiler, trust the _Bool type if the compiler has it.  */
-#  if !@HAVE__BOOL@
+#   if !@HAVE__BOOL@
+   /* For the sake of symbolic names in gdb, 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 then
+      values of type '_Bool' might 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 add a negative value to the
+      enum; this ensures that '_Bool' promotes to 'int'.  */
 typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
+#   endif
 #  endif
 # endif
+# define bool _Bool
 #endif
-#define bool _Bool
 
 /* The other macros must be usable in preprocessor directives.  */
-#define false 0
-#define true 1
+#ifdef __cplusplus
+# define false false
+# define true true
+#else
+# define false 0
+# define true 1
+#endif
+
 #define __bool_true_false_are_defined 1
 
 #endif /* _GL_STDBOOL_H */
diff --git a/gl/stddef.in.h b/gl/stddef.in.h
index e17ef24..614c9bc 100644
--- a/gl/stddef.in.h
+++ b/gl/stddef.in.h
@@ -1,6 +1,6 @@
 /* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues.
 
-   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+   Copyright (C) 2009-2013 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
diff --git a/gl/stdint.in.h b/gl/stdint.in.h
index 3a73abf..889bca7 100644
--- a/gl/stdint.in.h
+++ b/gl/stdint.in.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2002, 2004-2012 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2002, 2004-2013 Free Software Foundation, Inc.
    Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood.
    This file is part of gnulib.
 
@@ -39,7 +39,7 @@
    Ideally we should test __BIONIC__ here, but it is only defined after
    <sys/cdefs.h> has been included; hence test __ANDROID__ instead.  */
 #if defined __ANDROID__ \
-    && defined _SYS_TYPES_H_ && !defined _SSIZE_T_DEFINED_
+    && defined _SYS_TYPES_H_ && !defined __need_size_t
 # @INCLUDE_NEXT@ @NEXT_STDINT_H@
 #else
 
diff --git a/gl/stdlib.in.h b/gl/stdlib.in.h
index 72c9dd1..552fdf0 100644
--- a/gl/stdlib.in.h
+++ b/gl/stdlib.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <stdlib.h>.
 
-   Copyright (C) 1995, 2001-2004, 2006-2012 Free Software Foundation, Inc.
+   Copyright (C) 1995, 2001-2004, 2006-2013 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
@@ -20,8 +20,9 @@
 #endif
 @PRAGMA_COLUMNS@
 
-#if defined __need_malloc_and_calloc
-/* Special invocation convention inside glibc header files.  */
+#if defined __need_system_stdlib_h || defined __need_malloc_and_calloc
+/* Special invocation conventions inside some gnulib header files,
+   and inside some glibc header files, respectively.  */
 
 #@INCLUDE_NEXT@ @NEXT_STDLIB_H@
 
@@ -457,10 +458,19 @@ _GL_WARN_ON_USE (posix_openpt, "posix_openpt is not portable - "
 #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@
+# if @REPLACE_PTSNAME@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef ptsname
+#   define ptsname rpl_ptsname
+#  endif
+_GL_FUNCDECL_RPL (ptsname, char *, (int fd));
+_GL_CXXALIAS_RPL (ptsname, char *, (int fd));
+# else
+#  if !@HAVE_PTSNAME@
 _GL_FUNCDECL_SYS (ptsname, char *, (int fd));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (ptsname, char *, (int fd));
+# endif
 _GL_CXXALIASWARN (ptsname);
 #elif defined GNULIB_POSIXCHECK
 # undef ptsname
@@ -757,6 +767,22 @@ _GL_WARN_ON_USE (rpmatch, "rpmatch is unportable - "
 # endif
 #endif
 
+#if @GNULIB_SECURE_GETENV@
+/* Look up NAME in the environment, returning 0 in insecure situations.  */
+# if !@HAVE_SECURE_GETENV@
+_GL_FUNCDECL_SYS (secure_getenv, char *,
+                  (char const *name) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (secure_getenv, char *, (char const *name));
+_GL_CXXALIASWARN (secure_getenv);
+#elif defined GNULIB_POSIXCHECK
+# undef secure_getenv
+# if HAVE_RAW_DECL_SECURE_GETENV
+_GL_WARN_ON_USE (secure_getenv, "secure_getenv is unportable - "
+                 "use gnulib module secure_getenv for portability");
+# endif
+#endif
+
 #if @GNULIB_SETENV@
 /* Set NAME to VALUE in the environment.
    If REPLACE is nonzero, overwrite an existing value.  */
diff --git a/gl/strcasecmp.c b/gl/strcasecmp.c
deleted file mode 100644
index ec3c3e6..0000000
--- a/gl/strcasecmp.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Case-insensitive string comparison function.
-   Copyright (C) 1998-1999, 2005-2007, 2009-2012 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, see <http://www.gnu.org/licenses/>.  */
-
-#include <config.h>
-
-/* Specification.  */
-#include <string.h>
-
-#include <ctype.h>
-#include <limits.h>
-
-#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
-
-/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
-   greater than zero if S1 is lexicographically less than, equal to or greater
-   than S2.
-   Note: This function does not work with multibyte strings!  */
-
-int
-strcasecmp (const char *s1, const char *s2)
-{
-  const unsigned char *p1 = (const unsigned char *) s1;
-  const unsigned char *p2 = (const unsigned char *) s2;
-  unsigned char c1, c2;
-
-  if (p1 == p2)
-    return 0;
-
-  do
-    {
-      c1 = TOLOWER (*p1);
-      c2 = TOLOWER (*p2);
-
-      if (c1 == '\0')
-        break;
-
-      ++p1;
-      ++p2;
-    }
-  while (c1 == c2);
-
-  if (UCHAR_MAX <= INT_MAX)
-    return c1 - c2;
-  else
-    /* On machines where 'char' and 'int' are types of the same size, the
-       difference of two 'unsigned char' values - including the sign bit -
-       doesn't fit in an 'int'.  */
-    return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
-}
diff --git a/gl/streq.h b/gl/streq.h
index 7fd07c8..03ede61 100644
--- a/gl/streq.h
+++ b/gl/streq.h
@@ -1,5 +1,5 @@
 /* Optimized string comparison.
-   Copyright (C) 2001-2002, 2007, 2009-2012 Free Software Foundation, Inc.
+   Copyright (C) 2001-2002, 2007, 2009-2013 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
diff --git a/gl/strings.in.h b/gl/strings.in.h
deleted file mode 100644
index 95c4cf7..0000000
--- a/gl/strings.in.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* A substitute <strings.h>.
-
-   Copyright (C) 2007-2012 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef _ at GUARD_PREFIX@_STRINGS_H
-
-#if __GNUC__ >= 3
- at PRAGMA_SYSTEM_HEADER@
-#endif
- at PRAGMA_COLUMNS@
-
-/* Minix 3.1.8 has a bug: <sys/types.h> must be included before <strings.h>.
-   But avoid namespace pollution on glibc systems.  */
-#if defined __minix && !defined __GLIBC__
-# include <sys/types.h>
-#endif
-
-/* The include_next requires a split double-inclusion guard.  */
-#if @HAVE_STRINGS_H@
-# @INCLUDE_NEXT@ @NEXT_STRINGS_H@
-#endif
-
-#ifndef _ at GUARD_PREFIX@_STRINGS_H
-#define _ at GUARD_PREFIX@_STRINGS_H
-
-#if ! @HAVE_DECL_STRNCASECMP@
-/* Get size_t.  */
-# include <stddef.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.  */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-  /* Find the index of the least-significant set bit.  */
-#if @GNULIB_FFS@
-# if !@HAVE_FFS@
-_GL_FUNCDECL_SYS (ffs, int, (int i));
-# endif
-_GL_CXXALIAS_SYS (ffs, int, (int i));
-_GL_CXXALIASWARN (ffs);
-#elif defined GNULIB_POSIXCHECK
-# undef ffs
-# if HAVE_RAW_DECL_FFS
-_GL_WARN_ON_USE (ffs, "ffs is not portable - use the ffs module");
-# endif
-#endif
-
-/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
-   greater than zero if S1 is lexicographically less than, equal to or greater
-   than S2.
-   Note: This function does not work in multibyte locales.  */
-#if ! @HAVE_STRCASECMP@
-extern int strcasecmp (char const *s1, char const *s2)
-     _GL_ARG_NONNULL ((1, 2));
-#endif
-#if defined GNULIB_POSIXCHECK
-/* strcasecmp() does not work with multibyte strings:
-   POSIX says that it operates on "strings", and "string" in POSIX is defined
-   as a sequence of bytes, not of characters.   */
-# undef strcasecmp
-# if HAVE_RAW_DECL_STRCASECMP
-_GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character "
-                 "strings in multibyte locales - "
-                 "use mbscasecmp if you care about "
-                 "internationalization, or use c_strcasecmp , "
-                 "gnulib module c-strcase) if you want a locale "
-                 "independent function");
-# endif
-#endif
-
-/* Compare no more than N bytes of strings S1 and S2, ignoring case,
-   returning less than, equal to or greater than zero if S1 is
-   lexicographically less than, equal to or greater than S2.
-   Note: This function cannot work correctly in multibyte locales.  */
-#if ! @HAVE_DECL_STRNCASECMP@
-extern int strncasecmp (char const *s1, char const *s2, size_t n)
-     _GL_ARG_NONNULL ((1, 2));
-#endif
-#if defined GNULIB_POSIXCHECK
-/* strncasecmp() does not work with multibyte strings:
-   POSIX says that it operates on "strings", and "string" in POSIX is defined
-   as a sequence of bytes, not of characters.  */
-# undef strncasecmp
-# if HAVE_RAW_DECL_STRNCASECMP
-_GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character "
-                 "strings in multibyte locales - "
-                 "use mbsncasecmp or mbspcasecmp if you care about "
-                 "internationalization, or use c_strncasecmp , "
-                 "gnulib module c-strcase) if you want a locale "
-                 "independent function");
-# endif
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ at GUARD_PREFIX@_STRING_H */
-#endif /* _ at GUARD_PREFIX@_STRING_H */
diff --git a/gl/strncasecmp.c b/gl/strncasecmp.c
deleted file mode 100644
index a61d55f..0000000
--- a/gl/strncasecmp.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* strncasecmp.c -- case insensitive string comparator
-   Copyright (C) 1998-1999, 2005-2007, 2009-2012 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, see <http://www.gnu.org/licenses/>.  */
-
-#include <config.h>
-
-/* Specification.  */
-#include <string.h>
-
-#include <ctype.h>
-#include <limits.h>
-
-#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
-
-/* Compare no more than N bytes of strings S1 and S2, ignoring case,
-   returning less than, equal to or greater than zero if S1 is
-   lexicographically less than, equal to or greater than S2.
-   Note: This function cannot work correctly in multibyte locales.  */
-
-int
-strncasecmp (const char *s1, const char *s2, size_t n)
-{
-  register const unsigned char *p1 = (const unsigned char *) s1;
-  register const unsigned char *p2 = (const unsigned char *) s2;
-  unsigned char c1, c2;
-
-  if (p1 == p2 || n == 0)
-    return 0;
-
-  do
-    {
-      c1 = TOLOWER (*p1);
-      c2 = TOLOWER (*p2);
-
-      if (--n == 0 || c1 == '\0')
-        break;
-
-      ++p1;
-      ++p2;
-    }
-  while (c1 == c2);
-
-  if (UCHAR_MAX <= INT_MAX)
-    return c1 - c2;
-  else
-    /* On machines where 'char' and 'int' are types of the same size, the
-       difference of two 'unsigned char' values - including the sign bit -
-       doesn't fit in an 'int'.  */
-    return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
-}
diff --git a/gl/sys_types.in.h b/gl/sys_types.in.h
index 6eedaeb..520f6c8 100644
--- a/gl/sys_types.in.h
+++ b/gl/sys_types.in.h
@@ -1,6 +1,6 @@
 /* Provide a more complete sys/types.h.
 
-   Copyright (C) 2011-2012 Free Software Foundation, Inc.
+   Copyright (C) 2011-2013 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
diff --git a/gl/unistd.c b/gl/unistd.c
new file mode 100644
index 0000000..6c6a8e2
--- /dev/null
+++ b/gl/unistd.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#define _GL_UNISTD_INLINE _GL_EXTERN_INLINE
+#include "unistd.h"
diff --git a/gl/unistd.in.h b/gl/unistd.in.h
index e96a39c..9ffb1a7 100644
--- a/gl/unistd.in.h
+++ b/gl/unistd.in.h
@@ -1,5 +1,5 @@
 /* Substitute for and wrapper around <unistd.h>.
-   Copyright (C) 2003-2012 Free Software Foundation, Inc.
+   Copyright (C) 2003-2013 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
@@ -14,29 +14,13 @@
    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/>.  */
 
+#ifndef _ at GUARD_PREFIX@_UNISTD_H
+
 #if __GNUC__ >= 3
 @PRAGMA_SYSTEM_HEADER@
 #endif
 @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 _ at GUARD_PREFIX@_UNISTD_H
-
 /* The include_next requires a split double-inclusion guard.  */
 #if @HAVE_UNISTD_H@
 # @INCLUDE_NEXT@ @NEXT_UNISTD_H@
@@ -77,9 +61,13 @@
 /* mingw, MSVC, BeOS, Haiku declare environ in <stdlib.h>, not in
    <unistd.h>.  */
 /* Solaris declares getcwd not only in <unistd.h> but also in <stdlib.h>.  */
+/* OSF Tru64 Unix cannot see gnulib rpl_strtod when system <stdlib.h> is
+   included here.  */
 /* But avoid namespace pollution on glibc systems.  */
-#ifndef __GLIBC__
+#if !defined __GLIBC__ && !defined __osf__
+# define __need_system_stdlib_h
 # include <stdlib.h>
+# undef __need_system_stdlib_h
 #endif
 
 /* Native Windows platforms declare chdir, getcwd, rmdir in
@@ -124,9 +112,18 @@
 /* Get getopt(), optarg, optind, opterr, optopt.
    But avoid namespace pollution on glibc systems.  */
 #if @GNULIB_UNISTD_H_GETOPT@ && !defined __GLIBC__ && !defined _GL_SYSTEM_GETOPT
+# define __need_getopt
 # include <getopt.h>
 #endif
 
+#ifndef _GL_INLINE_HEADER_BEGIN
+ #error "Please include config.h first."
+#endif
+_GL_INLINE_HEADER_BEGIN
+#ifndef _GL_UNISTD_INLINE
+# define _GL_UNISTD_INLINE _GL_INLINE
+#endif
+
 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
@@ -404,7 +401,7 @@ extern char **environ;
 # endif
 #elif defined GNULIB_POSIXCHECK
 # if HAVE_RAW_DECL_ENVIRON
-static inline char ***
+_GL_UNISTD_INLINE char ***
 rpl_environ (void)
 {
   return &environ;
@@ -657,10 +654,19 @@ _GL_WARN_ON_USE (getdomainname, "getdomainname is unportable - "
 #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@
+# if @REPLACE_GETDTABLESIZE@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef getdtablesize
+#   define getdtablesize rpl_getdtablesize
+#  endif
+_GL_FUNCDECL_RPL (getdtablesize, int, (void));
+_GL_CXXALIAS_RPL (getdtablesize, int, (void));
+# else
+#  if !@HAVE_GETDTABLESIZE@
 _GL_FUNCDECL_SYS (getdtablesize, int, (void));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (getdtablesize, int, (void));
+# endif
 _GL_CXXALIASWARN (getdtablesize);
 #elif defined GNULIB_POSIXCHECK
 # undef getdtablesize
@@ -862,7 +868,7 @@ _GL_CXXALIAS_RPL (getpagesize, int, (void));
 #     define getpagesize() _gl_getpagesize ()
 #    else
 #     if !GNULIB_defined_getpagesize_function
-static inline int
+_GL_UNISTD_INLINE int
 getpagesize ()
 {
   return _gl_getpagesize ();
@@ -1530,6 +1536,7 @@ _GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t count));
 _GL_CXXALIASWARN (write);
 #endif
 
+_GL_INLINE_HEADER_END
 
 #endif /* _ at GUARD_PREFIX@_UNISTD_H */
 #endif /* _ at GUARD_PREFIX@_UNISTD_H */
diff --git a/gl/verify.h b/gl/verify.h
index 6c4bd43..13e2085 100644
--- a/gl/verify.h
+++ b/gl/verify.h
@@ -1,6 +1,6 @@
 /* Compile-time assert-like macros.
 
-   Copyright (C) 2005-2006, 2009-2012 Free Software Foundation, Inc.
+   Copyright (C) 2005-2006, 2009-2013 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
@@ -18,7 +18,7 @@
 /* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */
 
 #ifndef _GL_VERIFY_H
-# define _GL_VERIFY_H
+#define _GL_VERIFY_H
 
 
 /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11.
@@ -31,14 +31,24 @@
    Use this only with GCC.  If we were willing to slow 'configure'
    down we could also use it with other compilers, but since this
    affects only the quality of diagnostics, why bother?  */
-# if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus
-#  define _GL_HAVE__STATIC_ASSERT 1
-# endif
+#if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \
+     && (201112L <= __STDC_VERSION__  || !defined __STRICT_ANSI__) \
+     && !defined __cplusplus)
+# define _GL_HAVE__STATIC_ASSERT 1
+#endif
 /* The condition (99 < __GNUC__) is temporary, until we know about the
    first G++ release that supports static_assert.  */
-# if (99 < __GNUC__) && defined __cplusplus
-#  define _GL_HAVE_STATIC_ASSERT 1
-# endif
+#if (99 < __GNUC__) && defined __cplusplus
+# define _GL_HAVE_STATIC_ASSERT 1
+#endif
+
+/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
+   system headers, defines a conflicting _Static_assert that is no
+   better than ours; override it.  */
+#ifndef _GL_HAVE_STATIC_ASSERT
+# include <stddef.h>
+# undef _Static_assert
+#endif
 
 /* Each of these macros verifies that its argument R is nonzero.  To
    be portable, R should be an integer constant expression.  Unlike
@@ -125,7 +135,7 @@
        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
+     -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.
 
@@ -133,54 +143,58 @@
      which do not support _Static_assert, also do not warn about the
      last declaration mentioned above.
 
+   * GCC warns if -Wnested-externs is enabled and verify() is used
+     within a function body; but inside a function, you can always
+     arrange to use verify_expr() instead.
+
    * 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
+#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
+#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)
+#define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
 
 /* Verify requirement R at compile-time, as an integer constant expression
    that returns 1.  If R is false, fail at compile-time, preferably
    with a diagnostic that includes the string-literal DIAGNOSTIC.  */
 
-# define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \
-    (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))
+#define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \
+   (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))
 
-# ifdef __cplusplus
-#  if !GNULIB_defined_struct__gl_verify_type
+#ifdef __cplusplus
+# if !GNULIB_defined_struct__gl_verify_type
 template <int w>
   struct _gl_verify_type {
     unsigned int _gl_verify_error_if_negative: w;
   };
-#   define GNULIB_defined_struct__gl_verify_type 1
-#  endif
-#  define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
-    _gl_verify_type<(R) ? 1 : -1>
-# elif defined _GL_HAVE__STATIC_ASSERT
-#  define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
-     struct {                                   \
-       _Static_assert (R, DIAGNOSTIC);          \
-       int _gl_dummy;                          \
-     }
-# else
-#  define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
-     struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
+#  define GNULIB_defined_struct__gl_verify_type 1
 # endif
+# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
+    _gl_verify_type<(R) ? 1 : -1>
+#elif defined _GL_HAVE__STATIC_ASSERT
+# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
+    struct {                                   \
+      _Static_assert (R, DIAGNOSTIC);          \
+      int _gl_dummy;                          \
+    }
+#else
+# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
+    struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
+#endif
 
 /* Verify requirement R at compile-time, as a declaration without a
    trailing ';'.  If R is false, fail at compile-time, preferably
@@ -189,23 +203,23 @@ template <int w>
    Unfortunately, unlike C11, this implementation must appear as an
    ordinary declaration, and cannot appear inside struct { ... }.  */
 
-# ifdef _GL_HAVE__STATIC_ASSERT
-#  define _GL_VERIFY _Static_assert
-# else
-#  define _GL_VERIFY(R, DIAGNOSTIC)				       \
-     extern int (*_GL_GENSYM (_gl_verify_function) (void))	       \
-       [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
-# endif
+#ifdef _GL_HAVE__STATIC_ASSERT
+# define _GL_VERIFY _Static_assert
+#else
+# define _GL_VERIFY(R, DIAGNOSTIC)				       \
+    extern int (*_GL_GENSYM (_gl_verify_function) (void))	       \
+      [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
+#endif
 
 /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h.  */
-# ifdef _GL_STATIC_ASSERT_H
-#  if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert
-#   define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC)
-#  endif
-#  if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert
-#   define static_assert _Static_assert /* C11 requires this #define.  */
-#  endif
+#ifdef _GL_STATIC_ASSERT_H
+# if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert
+#  define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC)
+# endif
+# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert
+#  define static_assert _Static_assert /* C11 requires this #define.  */
 # endif
+#endif
 
 /* @assert.h omit start@  */
 
@@ -223,18 +237,42 @@ template <int w>
 
    verify_true is obsolescent; please use verify_expr instead.  */
 
-# define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")")
+#define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")")
 
 /* Verify requirement R at compile-time.  Return the value of the
    expression E.  */
 
-# define verify_expr(R, E) \
-    (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E))
+#define verify_expr(R, E) \
+   (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E))
 
 /* Verify requirement R at compile-time, as a declaration without a
    trailing ';'.  */
 
-# define verify(R) _GL_VERIFY (R, "verify (" #R ")")
+#define verify(R) _GL_VERIFY (R, "verify (" #R ")")
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/* Assume that R always holds.  This lets the compiler optimize
+   accordingly.  R should not have side-effects; it may or may not be
+   evaluated.  Behavior is undefined if R is false.  */
+
+#if (__has_builtin (__builtin_unreachable) \
+     || 4 < __GNUC__ + (5 <= __GNUC_MINOR__))
+# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
+#elif 1200 <= _MSC_VER
+# define assume(R) __assume (R)
+#elif (defined lint \
+       && (__has_builtin (__builtin_trap) \
+           || 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))))
+  /* Doing it this way helps various packages when configured with
+     --enable-gcc-warnings, which compiles with -Dlint.  It's nicer
+     when 'assume' silences warnings even with older GCCs.  */
+# define assume(R) ((R) ? (void) 0 : __builtin_trap ())
+#else
+# define assume(R) ((void) (0 && (R)))
+#endif
 
 /* @assert.h omit end@  */
 
diff --git a/gl/wchar.in.h b/gl/wchar.in.h
index 5c93616..97f7dc8 100644
--- a/gl/wchar.in.h
+++ b/gl/wchar.in.h
@@ -1,6 +1,6 @@
 /* A substitute for ISO C99 <wchar.h>, for platforms that have issues.
 
-   Copyright (C) 2007-2012 Free Software Foundation, Inc.
+   Copyright (C) 2007-2013 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
diff --git a/gl/wcrtomb.c b/gl/wcrtomb.c
index a4d6bcd..0aab985 100644
--- a/gl/wcrtomb.c
+++ b/gl/wcrtomb.c
@@ -1,5 +1,5 @@
 /* Convert wide character to multibyte character.
-   Copyright (C) 2008-2012 Free Software Foundation, Inc.
+   Copyright (C) 2008-2013 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
diff --git a/gl/wctype-h.c b/gl/wctype-h.c
new file mode 100644
index 0000000..bb5f847
--- /dev/null
+++ b/gl/wctype-h.c
@@ -0,0 +1,4 @@
+/* Normally this would be wctype.c, but that name's already taken.  */
+#include <config.h>
+#define _GL_WCTYPE_INLINE _GL_EXTERN_INLINE
+#include "wctype.h"
diff --git a/gl/wctype.in.h b/gl/wctype.in.h
index e819d44..58835c7 100644
--- a/gl/wctype.in.h
+++ b/gl/wctype.in.h
@@ -1,6 +1,6 @@
 /* A substitute for ISO C99 <wctype.h>, for platforms that lack it.
 
-   Copyright (C) 2006-2012 Free Software Foundation, Inc.
+   Copyright (C) 2006-2013 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
@@ -44,6 +44,13 @@
 # include <wchar.h>
 #endif
 
+/* mingw has declarations of towupper and towlower in <ctype.h> as
+   well <wctype.h>.  Include <ctype.h> in advance to avoid rpl_ prefix
+   being added to the declarations.  */
+#ifdef __MINGW32__
+# include <ctype.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.  */
@@ -54,6 +61,14 @@
 #ifndef _ at GUARD_PREFIX@_WCTYPE_H
 #define _ at GUARD_PREFIX@_WCTYPE_H
 
+#ifndef _GL_INLINE_HEADER_BEGIN
+ #error "Please include config.h first."
+#endif
+_GL_INLINE_HEADER_BEGIN
+#ifndef _GL_WCTYPE_INLINE
+# define _GL_WCTYPE_INLINE _GL_INLINE
+#endif
+
 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
 
 /* The definition of _GL_WARN_ON_USE is copied here.  */
@@ -148,7 +163,7 @@ typedef unsigned int rpl_wint_t;
 #   endif
 #  endif
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswalnum
 #  else
@@ -160,7 +175,7 @@ iswalnum
           || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'));
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswalpha
 #  else
@@ -171,7 +186,7 @@ iswalpha
   return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z';
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswblank
 #  else
@@ -182,7 +197,7 @@ iswblank
   return wc == ' ' || wc == '\t';
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswcntrl
 #  else
@@ -193,7 +208,7 @@ iswcntrl
   return (wc & ~0x1f) == 0 || wc == 0x7f;
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswdigit
 #  else
@@ -204,7 +219,7 @@ iswdigit
   return wc >= '0' && wc <= '9';
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswgraph
 #  else
@@ -215,7 +230,7 @@ iswgraph
   return wc >= '!' && wc <= '~';
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswlower
 #  else
@@ -226,7 +241,7 @@ iswlower
   return wc >= 'a' && wc <= 'z';
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswprint
 #  else
@@ -237,7 +252,7 @@ iswprint
   return wc >= ' ' && wc <= '~';
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswpunct
 #  else
@@ -250,7 +265,7 @@ iswpunct
                || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')));
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswspace
 #  else
@@ -262,7 +277,7 @@ iswspace
           || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r');
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswupper
 #  else
@@ -273,7 +288,7 @@ iswupper
   return wc >= 'A' && wc <= 'Z';
 }
 
-static inline int
+_GL_WCTYPE_INLINE int
 #  if @REPLACE_ISWCNTRL@
 rpl_iswxdigit
 #  else
@@ -285,7 +300,7 @@ iswxdigit
           || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F'));
 }
 
-static inline wint_t
+_GL_WCTYPE_INLINE wint_t
 #  if @REPLACE_TOWLOWER@
 rpl_towlower
 #  else
@@ -296,7 +311,7 @@ towlower
   return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc);
 }
 
-static inline wint_t
+_GL_WCTYPE_INLINE wint_t
 #  if @REPLACE_TOWLOWER@
 rpl_towupper
 #  else
@@ -336,7 +351,7 @@ _GL_FUNCDECL_SYS (iswblank, int, (wint_t wc));
       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
+_GL_WCTYPE_INLINE wint_t
 rpl_towlower (wint_t wc)
 {
   return (wint_t) (wchar_t) towlower (wc);
@@ -345,7 +360,7 @@ rpl_towlower (wint_t wc)
 #   define towlower rpl_towlower
 #  endif
 
-static inline wint_t
+_GL_WCTYPE_INLINE wint_t
 rpl_towupper (wint_t wc)
 {
   return (wint_t) (wchar_t) towupper (wc);
@@ -493,6 +508,7 @@ _GL_WARN_ON_USE (towctrans, "towctrans is unportable - "
 # endif
 #endif
 
+_GL_INLINE_HEADER_END
 
 #endif /* _ at GUARD_PREFIX@_WCTYPE_H */
 #endif /* _ at GUARD_PREFIX@_WCTYPE_H */
diff --git a/lex.Error.cc b/lex.Error.cc
index 58c7187..6242fd3 100644
--- a/lex.Error.cc
+++ b/lex.Error.cc
@@ -66,6 +66,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -172,7 +173,12 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int Errorleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t Errorleng;
 
 extern FILE *Errorin, *Errorout;
 
@@ -198,11 +204,6 @@ extern FILE *Errorin, *Errorout;
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -220,7 +221,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t 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
@@ -290,8 +291,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
 
 /* 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;
+static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t Errorleng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
@@ -319,7 +320,7 @@ static void Error_init_buffer (YY_BUFFER_STATE b,FILE *file  );
 
 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  );
+YY_BUFFER_STATE Error_scan_bytes (yyconst char *bytes,yy_size_t len  );
 
 void *Erroralloc (yy_size_t  );
 void *Errorrealloc (void *,yy_size_t  );
@@ -378,7 +379,7 @@ static void yy_fatal_error (yyconst char msg[]  );
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
 	(yytext_ptr) -= (yy_more_len); \
-	Errorleng = (size_t) (yy_cp - (yytext_ptr)); \
+	Errorleng = (yy_size_t) (yy_cp - (yytext_ptr)); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
@@ -559,7 +560,7 @@ char *Errortext;
 
 #include "config_dap.h"
 
-static char rcsid[] not_used = {"$Id: Error.lex 27157 2013-09-28 21:22:52Z jimg $"};
+static char rcsid[] not_used = {"$Id$"};
 
 #include <cstdlib>
 #include <cassert>
@@ -593,7 +594,7 @@ void store_string();
 #define YY_NO_INPUT 1
 
 
-#line 597 "lex.Error.cc"
+#line 598 "lex.Error.cc"
 
 #define INITIAL 0
 #define quote 1
@@ -634,7 +635,7 @@ FILE *Errorget_out (void );
 
 void Errorset_out  (FILE * out_str  );
 
-int Errorget_leng (void );
+yy_size_t Errorget_leng (void );
 
 char *Errorget_text (void );
 
@@ -682,7 +683,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( Errortext, Errorleng, 1, Errorout )) {} } while (0)
+#define ECHO fwrite( Errortext, Errorleng, 1, Errorout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -693,7 +694,7 @@ static int input (void );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		unsigned n; \
+		yy_size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( Errorin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -779,7 +780,7 @@ YY_DECL
 
 
 
-#line 783 "lex.Error.cc"
+#line 784 "lex.Error.cc"
 
 	if ( !(yy_init) )
 		{
@@ -1000,7 +1001,7 @@ YY_RULE_SETUP
 #line 144 "Error.lex"
 ECHO;
 	YY_BREAK
-#line 1004 "lex.Error.cc"
+#line 1005 "lex.Error.cc"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1184,7 +1185,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1198,7 +1199,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1229,7 +1230,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1351,7 +1352,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1375,7 +1376,7 @@ static int yy_get_next_buffer (void)
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( Errorwrap( ) )
-						return EOF;
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1627,7 +1628,7 @@ void Errorpop_buffer_state (void)
  */
 static void Errorensure_buffer_stack (void)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1724,12 +1725,11 @@ YY_BUFFER_STATE Error_scan_string (yyconst char * yystr )
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE Error_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+YY_BUFFER_STATE Error_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
-	yy_size_t n;
-	int i;
+	yy_size_t n, i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	n = _yybytes_len + 2;
@@ -1811,7 +1811,7 @@ FILE *Errorget_out  (void)
 /** Get the length of the current token.
  * 
  */
-int Errorget_leng  (void)
+yy_size_t Errorget_leng  (void)
 {
         return Errorleng;
 }
diff --git a/lex.ce_expr.cc b/lex.ce_expr.cc
index 8d2a9d6..f4e2fad 100644
--- a/lex.ce_expr.cc
+++ b/lex.ce_expr.cc
@@ -66,6 +66,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -172,7 +173,12 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int ce_exprleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t ce_exprleng;
 
 extern FILE *ce_exprin, *ce_exprout;
 
@@ -198,11 +204,6 @@ extern FILE *ce_exprin, *ce_exprout;
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -220,7 +221,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t 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
@@ -290,8 +291,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
 
 /* 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;
+static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t ce_exprleng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
@@ -319,7 +320,7 @@ static void ce_expr_init_buffer (YY_BUFFER_STATE b,FILE *file  );
 
 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  );
+YY_BUFFER_STATE ce_expr_scan_bytes (yyconst char *bytes,yy_size_t len  );
 
 void *ce_expralloc (yy_size_t  );
 void *ce_exprrealloc (void *,yy_size_t  );
@@ -378,7 +379,7 @@ static void yy_fatal_error (yyconst char msg[]  );
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
 	(yytext_ptr) -= (yy_more_len); \
-	ce_exprleng = (size_t) (yy_cp - (yytext_ptr)); \
+	ce_exprleng = (yy_size_t) (yy_cp - (yytext_ptr)); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
@@ -567,8 +568,6 @@ char *ce_exprtext;
 
 #include "config.h"
 
-static char rcsid[] not_used = {"$Id: ce_expr.lex 27157 2013-09-28 21:22:52Z jimg $"};
-
 #include <cstdio>
 #include <string>
 #include <cstring>
@@ -613,7 +612,7 @@ static void store_op(int op);
    scanners, but not here because it'll conflict with the url dereference
    operator. 6/10/2002 jhrg
 */
-#line 617 "lex.ce_expr.cc"
+#line 616 "lex.ce_expr.cc"
 
 #define INITIAL 0
 #define quote 1
@@ -653,7 +652,7 @@ FILE *ce_exprget_out (void );
 
 void ce_exprset_out  (FILE * out_str  );
 
-int ce_exprget_leng (void );
+yy_size_t ce_exprget_leng (void );
 
 char *ce_exprget_text (void );
 
@@ -701,7 +700,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( ce_exprtext, ce_exprleng, 1, ce_exprout )) {} } while (0)
+#define ECHO fwrite( ce_exprtext, ce_exprleng, 1, ce_exprout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -712,7 +711,7 @@ static int input (void );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		unsigned n; \
+		yy_size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( ce_exprin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -794,10 +793,10 @@ YY_DECL
 	register char *yy_cp, *yy_bp;
 	register int yy_act;
     
-#line 132 "ce_expr.lex"
+#line 130 "ce_expr.lex"
 
 
-#line 801 "lex.ce_expr.cc"
+#line 800 "lex.ce_expr.cc"
 
 	if ( !(yy_init) )
 		{
@@ -888,158 +887,158 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 134 "ce_expr.lex"
+#line 132 "ce_expr.lex"
 return (int)*ce_exprtext;
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 135 "ce_expr.lex"
+#line 133 "ce_expr.lex"
 return (int)*ce_exprtext;
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 136 "ce_expr.lex"
+#line 134 "ce_expr.lex"
 return (int)*ce_exprtext;
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 137 "ce_expr.lex"
+#line 135 "ce_expr.lex"
 return (int)*ce_exprtext;
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 138 "ce_expr.lex"
+#line 136 "ce_expr.lex"
 return (int)*ce_exprtext;
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 139 "ce_expr.lex"
+#line 137 "ce_expr.lex"
 return (int)*ce_exprtext;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 140 "ce_expr.lex"
+#line 138 "ce_expr.lex"
 return (int)*ce_exprtext;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 141 "ce_expr.lex"
+#line 139 "ce_expr.lex"
 return (int)*ce_exprtext;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 142 "ce_expr.lex"
+#line 140 "ce_expr.lex"
 return (int)*ce_exprtext;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 144 "ce_expr.lex"
+#line 142 "ce_expr.lex"
 store_id(); return SCAN_WORD;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 146 "ce_expr.lex"
+#line 144 "ce_expr.lex"
 store_op(SCAN_EQUAL); return SCAN_EQUAL;
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 147 "ce_expr.lex"
+#line 145 "ce_expr.lex"
 store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 148 "ce_expr.lex"
+#line 146 "ce_expr.lex"
 store_op(SCAN_GREATER); return SCAN_GREATER;
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 149 "ce_expr.lex"
+#line 147 "ce_expr.lex"
 store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 150 "ce_expr.lex"
+#line 148 "ce_expr.lex"
 store_op(SCAN_LESS); return SCAN_LESS;
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 151 "ce_expr.lex"
+#line 149 "ce_expr.lex"
 store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 152 "ce_expr.lex"
+#line 150 "ce_expr.lex"
 store_op(SCAN_REGEXP); return SCAN_REGEXP;
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 154 "ce_expr.lex"
+#line 152 "ce_expr.lex"
 store_op(SCAN_STAR); return SCAN_STAR;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 156 "ce_expr.lex"
+#line 154 "ce_expr.lex"
 return SCAN_HASH_BYTE;
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 157 "ce_expr.lex"
+#line 155 "ce_expr.lex"
 return SCAN_HASH_INT16;
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 158 "ce_expr.lex"
+#line 156 "ce_expr.lex"
 return SCAN_HASH_UINT16;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 159 "ce_expr.lex"
+#line 157 "ce_expr.lex"
 return SCAN_HASH_INT32;
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 160 "ce_expr.lex"
+#line 158 "ce_expr.lex"
 return SCAN_HASH_UINT32;
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 161 "ce_expr.lex"
+#line 159 "ce_expr.lex"
 return SCAN_HASH_FLOAT32;
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 162 "ce_expr.lex"
+#line 160 "ce_expr.lex"
 return SCAN_HASH_FLOAT64;
 	YY_BREAK
 case 26:
 /* rule 26 can match eol */
 YY_RULE_SETUP
-#line 164 "ce_expr.lex"
+#line 162 "ce_expr.lex"
 
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
-#line 165 "ce_expr.lex"
+#line 163 "ce_expr.lex"
 yy_init = 1; yyterminate();
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 167 "ce_expr.lex"
+#line 165 "ce_expr.lex"
 BEGIN(quote); yymore();
 	YY_BREAK
 case 28:
 /* rule 28 can match eol */
 YY_RULE_SETUP
-#line 169 "ce_expr.lex"
+#line 167 "ce_expr.lex"
 yymore(); /*"*/
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 171 "ce_expr.lex"
+#line 169 "ce_expr.lex"
 yymore();
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 173 "ce_expr.lex"
+#line 171 "ce_expr.lex"
 { 
     		  BEGIN(INITIAL); 
               store_str();
@@ -1047,7 +1046,7 @@ YY_RULE_SETUP
             }
 	YY_BREAK
 case YY_STATE_EOF(quote):
-#line 179 "ce_expr.lex"
+#line 177 "ce_expr.lex"
 {
                   BEGIN(INITIAL);   /* resetting the state is needed for reentrant parsers */
                   char msg[256];
@@ -1058,7 +1057,7 @@ case YY_STATE_EOF(quote):
 case 31:
 /* rule 31 can match eol */
 YY_RULE_SETUP
-#line 186 "ce_expr.lex"
+#line 184 "ce_expr.lex"
 {
                   if (ce_exprtext) {	/* suppress msgs about `' chars */
                     fprintf(stderr, "Character `%c' is not", *ce_exprtext);
@@ -1068,10 +1067,10 @@ YY_RULE_SETUP
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 192 "ce_expr.lex"
+#line 190 "ce_expr.lex"
 ECHO;
 	YY_BREAK
-#line 1075 "lex.ce_expr.cc"
+#line 1074 "lex.ce_expr.cc"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1255,7 +1254,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1269,7 +1268,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1300,7 +1299,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1422,7 +1421,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1446,7 +1445,7 @@ static int yy_get_next_buffer (void)
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( ce_exprwrap( ) )
-						return EOF;
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1698,7 +1697,7 @@ void ce_exprpop_buffer_state (void)
  */
 static void ce_exprensure_buffer_stack (void)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1795,12 +1794,11 @@ YY_BUFFER_STATE ce_expr_scan_string (yyconst char * yystr )
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE ce_expr_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+YY_BUFFER_STATE ce_expr_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
-	yy_size_t n;
-	int i;
+	yy_size_t n, i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	n = _yybytes_len + 2;
@@ -1882,7 +1880,7 @@ FILE *ce_exprget_out  (void)
 /** Get the length of the current token.
  * 
  */
-int ce_exprget_leng  (void)
+yy_size_t ce_exprget_leng  (void)
 {
         return ce_exprleng;
 }
@@ -2030,7 +2028,7 @@ void ce_exprfree (void * ptr )
 
 #define YYTABLES_NAME "yytables"
 
-#line 192 "ce_expr.lex"
+#line 190 "ce_expr.lex"
 
 
 
diff --git a/lex.das.cc b/lex.das.cc
index b85c284..c4259c1 100644
--- a/lex.das.cc
+++ b/lex.das.cc
@@ -66,6 +66,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -172,7 +173,12 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int dasleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t dasleng;
 
 extern FILE *dasin, *dasout;
 
@@ -198,11 +204,6 @@ extern FILE *dasin, *dasout;
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -220,7 +221,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t 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
@@ -290,8 +291,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
 
 /* 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;
+static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t dasleng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
@@ -319,7 +320,7 @@ static void das_init_buffer (YY_BUFFER_STATE b,FILE *file  );
 
 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  );
+YY_BUFFER_STATE das_scan_bytes (yyconst char *bytes,yy_size_t len  );
 
 void *dasalloc (yy_size_t  );
 void *dasrealloc (void *,yy_size_t  );
@@ -378,7 +379,7 @@ static void yy_fatal_error (yyconst char msg[]  );
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
 	(yytext_ptr) -= (yy_more_len); \
-	dasleng = (size_t) (yy_cp - (yytext_ptr)); \
+	dasleng = (yy_size_t) (yy_cp - (yytext_ptr)); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
@@ -670,7 +671,7 @@ char *dastext;
 
 #include <cstdio>
 
-static char rcsid[] not_used ={"$Id: das.lex 27157 2013-09-28 21:22:52Z jimg $"};
+static char rcsid[] not_used ={"$Id$"};
 
 #ifndef _MSC_VER
 #include <string.h>
@@ -711,7 +712,7 @@ static int start_line;		/* used in quote and comment error handlers */
    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 715 "lex.das.cc"
+#line 716 "lex.das.cc"
 
 #define INITIAL 0
 #define quote 1
@@ -753,7 +754,7 @@ FILE *dasget_out (void );
 
 void dasset_out  (FILE * out_str  );
 
-int dasget_leng (void );
+yy_size_t dasget_leng (void );
 
 char *dasget_text (void );
 
@@ -801,7 +802,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( dastext, dasleng, 1, dasout )) {} } while (0)
+#define ECHO fwrite( dastext, dasleng, 1, dasout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -812,7 +813,7 @@ static int input (void );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		unsigned n; \
+		yy_size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( dasin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -897,7 +898,7 @@ YY_DECL
 #line 136 "das.lex"
 
 
-#line 901 "lex.das.cc"
+#line 902 "lex.das.cc"
 
 	if ( !(yy_init) )
 		{
@@ -1181,7 +1182,7 @@ YY_RULE_SETUP
 #line 200 "das.lex"
 ECHO;
 	YY_BREAK
-#line 1185 "lex.das.cc"
+#line 1186 "lex.das.cc"
 case YY_STATE_EOF(xml):
 	yyterminate();
 
@@ -1367,7 +1368,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1381,7 +1382,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1412,7 +1413,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1534,7 +1535,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1558,7 +1559,7 @@ static int yy_get_next_buffer (void)
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( daswrap( ) )
-						return EOF;
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1810,7 +1811,7 @@ void daspop_buffer_state (void)
  */
 static void dasensure_buffer_stack (void)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1907,12 +1908,11 @@ YY_BUFFER_STATE das_scan_string (yyconst char * yystr )
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE das_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+YY_BUFFER_STATE das_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
-	yy_size_t n;
-	int i;
+	yy_size_t n, i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	n = _yybytes_len + 2;
@@ -1994,7 +1994,7 @@ FILE *dasget_out  (void)
 /** Get the length of the current token.
  * 
  */
-int dasget_leng  (void)
+yy_size_t dasget_leng  (void)
 {
         return dasleng;
 }
diff --git a/lex.dds.cc b/lex.dds.cc
index 3992803..f02a51b 100644
--- a/lex.dds.cc
+++ b/lex.dds.cc
@@ -66,6 +66,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -172,7 +173,12 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int ddsleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t ddsleng;
 
 extern FILE *ddsin, *ddsout;
 
@@ -198,11 +204,6 @@ extern FILE *ddsin, *ddsout;
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -220,7 +221,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t 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
@@ -290,8 +291,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
 
 /* 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;
+static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t ddsleng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
@@ -319,7 +320,7 @@ static void dds_init_buffer (YY_BUFFER_STATE b,FILE *file  );
 
 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  );
+YY_BUFFER_STATE dds_scan_bytes (yyconst char *bytes,yy_size_t len  );
 
 void *ddsalloc (yy_size_t  );
 void *ddsrealloc (void *,yy_size_t  );
@@ -377,7 +378,7 @@ static void yy_fatal_error (yyconst char msg[]  );
  */
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
-	ddsleng = (size_t) (yy_cp - yy_bp); \
+	ddsleng = (yy_size_t) (yy_cp - yy_bp); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
@@ -683,7 +684,7 @@ static void store_word();
 
 /* See das.lex for comments about the characters allowed in a WORD.
    10/31/2001 jhrg */
-#line 687 "lex.dds.cc"
+#line 688 "lex.dds.cc"
 
 #define INITIAL 0
 #define comment 1
@@ -723,7 +724,7 @@ FILE *ddsget_out (void );
 
 void ddsset_out  (FILE * out_str  );
 
-int ddsget_leng (void );
+yy_size_t ddsget_leng (void );
 
 char *ddsget_text (void );
 
@@ -771,7 +772,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( ddstext, ddsleng, 1, ddsout )) {} } while (0)
+#define ECHO fwrite( ddstext, ddsleng, 1, ddsout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -782,7 +783,7 @@ static int input (void );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		unsigned n; \
+		yy_size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( ddsin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -867,7 +868,7 @@ YY_DECL
 #line 120 "dds.lex"
 
 
-#line 871 "lex.dds.cc"
+#line 872 "lex.dds.cc"
 
 	if ( !(yy_init) )
 		{
@@ -1123,7 +1124,7 @@ YY_RULE_SETUP
 #line 165 "dds.lex"
 ECHO;
 	YY_BREAK
-#line 1127 "lex.dds.cc"
+#line 1128 "lex.dds.cc"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1307,7 +1308,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1321,7 +1322,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1352,7 +1353,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -1474,7 +1475,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1498,7 +1499,7 @@ static int yy_get_next_buffer (void)
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( ddswrap( ) )
-						return EOF;
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -1750,7 +1751,7 @@ void ddspop_buffer_state (void)
  */
 static void ddsensure_buffer_stack (void)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1847,12 +1848,11 @@ YY_BUFFER_STATE dds_scan_string (yyconst char * yystr )
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE dds_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+YY_BUFFER_STATE dds_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
-	yy_size_t n;
-	int i;
+	yy_size_t n, i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	n = _yybytes_len + 2;
@@ -1934,7 +1934,7 @@ FILE *ddsget_out  (void)
 /** Get the length of the current token.
  * 
  */
-int ddsget_leng  (void)
+yy_size_t ddsget_leng  (void)
 {
         return ddsleng;
 }
diff --git a/libdap.spec b/libdap.spec
index 97b6d45..56cbc44 100644
--- a/libdap.spec
+++ b/libdap.spec
@@ -1,17 +1,17 @@
 Name: libdap
-Summary: The C++ DAP2 library from OPeNDAP
-Version: 3.12.0
-Release: 1
+Summary: The C++ DAP2/DAP4 library from OPeNDAP
+Version: 3.14.0
+Release: 1%{?dist}
 
 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
+Requires: curl >= 7.19.0 libxml2 >= 2.7.0
 
 BuildRoot:  %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
-BuildRequires: curl-devel >= 7.10.6 libxml2-devel >= 2.6.16
+BuildRequires: curl-devel >= 7.19.0 libxml2-devel >= 2.7.0
 # BuildRequires: doxygen graphviz
 BuildRequires: pkgconfig
 
@@ -19,28 +19,27 @@ BuildRequires: pkgconfig
 # 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.
+%description 
+The libdap library contains an implementation of DAP2 and DAP4. This
+package contains the library, dap-config, getdap and getdap4. The
+script dap-config simplifies using the library in other projects. The
+getdap and getdap4 utilities are a simple command-line tool to read
+from DAP2 and DAP4 servers and are built using the library to
+demonstrates simple uses of it. Note that libdap used to include a
+copy of 'deflate' which was used to compress responses.
 
 %package devel
-Summary: Development and header files from libdap
+Summary: Development and header files for libdap
 Group: Development/Libraries
 Requires: %{name} = %{version}-%{release}
-Requires: curl-devel >= 7.10.6 libxml2-devel >= 2.6.16
+Requires: curl-devel >= 7.19.0 libxml2-devel >= 2.7.0
 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.
+use libdap.
 
 # %package doc
 # Summary: Documentation of the libdap library
@@ -82,6 +81,7 @@ rm -rf $RPM_BUILD_ROOT
 %files
 %defattr(-,root,root,-)
 %{_bindir}/getdap
+%{_bindir}/getdap4
 %{_libdir}/libdap.so.*
 %{_libdir}/libtest-types.a
 %{_libdir}/libdapclient.so.*
@@ -110,8 +110,6 @@ rm -rf $RPM_BUILD_ROOT
 * 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
 
diff --git a/ResponseTooBigErr.cc b/media_types.h
similarity index 51%
copy from ResponseTooBigErr.cc
copy to media_types.h
index 8847427..54e9575 100644
--- a/ResponseTooBigErr.cc
+++ b/media_types.h
@@ -1,10 +1,9 @@
-
 // -*- 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.
+// Copyright (c) 2013 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -24,29 +23,32 @@
 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
 
-#include "config.h"
+#ifndef MEDIA_TYPES_H_
+#define MEDIA_TYPES_H_
+
+static std::string DAS1 = "dods_das";
+static std::string DAS2 = "dods-das";
 
-static char rcsid[] not_used =
-    {"$Id: ResponseTooBigErr.cc 27197 2013-10-01 21:29:54Z jimg $"
-    };
+static std::string DDS1 = "dods_dds";
+static std::string DDS2 = "dods-dds";
 
-#include <string>
+static std::string DAP2_DATA1 = "dods_data";
+static std::string DAP2_DATA2 = "dods-data";
 
-#include "ResponseTooBigErr.h"
+static std::string DDX1 = "dods_ddx";
+static std::string DDX2 = "dods-ddx";
 
-namespace libdap {
+static std::string DAP2_ERR1 = "dods_error";
+static std::string DAP2_ERR2 = "dods-error";
 
-ResponseTooBigErr::ResponseTooBigErr() : Error()
-{
-    _error_code = unknown_error;
-}
+static std::string WEB_ERR1 = "web_error";
+static std::string WEB_ERR2 = "web-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";
-}
+static std::string DAP4_DMR = "dap4-dmr";
+static std::string DAP4_DATA = "dap4-data";
+static std::string DAP4_ERR ="dap4-error";
 
-} // namespace libdap
+static const std::string DMR_Content_Type = "application/vnd.opendap.dap4.dataset-metadata";
+static const std::string DAP4_DATA_Content_Type = "application/vnd.opendap.dap4.data";
+// application/vnd.opendap.dap4.data
+#endif /* MEDIA_TYPES_H_ */
diff --git a/mime_util.cc b/mime_util.cc
index b8cd473..64bd908 100644
--- a/mime_util.cc
+++ b/mime_util.cc
@@ -67,6 +67,8 @@
 #include <string>
 
 #include "mime_util.h"
+#include "media_types.h"
+
 #include "Ancillary.h"
 #include "util.h"  // This supplies flush_stream for WIN32.
 #include "debug.h"
@@ -289,12 +291,28 @@ name_path(const string &path)
 //
 // Returns: false if the compression output filter was to be used but could
 // not be started, true otherwise.
-
+#if 0
 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"
+    {"unknown", "dods_das", "dods_dds", "dods_data", "dods_ddx",
+     "dods_error", "web_error", "dap4-dmr", "dap4-data", "dap4-error"
     };
+#endif
+
+static const char *descrip[] = {
+"unknown_type",
+"dods_das",
+"dods_dds",
+"dods_data",
+"dods_ddx",       // This is the old XML DDS/DAS used prior to dap4
+"dods_data_ddx",  // This is used for caching data responses
+"dods_error",
+"web_error",
+
+"dap4_dmr",       // DAP4 metadata
+"dap4_data",      // The DMR with a data blob
+"dap4_error"      // The error response for DAP4
+};
+
 static const char *encoding[] =
     {"unknown", "deflate", "x-plain", "gzip", "binary"
     };
@@ -307,30 +325,11 @@ static const char *encoding[] =
 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;
+	return get_description_type(value);
 }
 
+// TODO Recode to use the constants in media_types.h. jhrg 11/12/13
+
 /** 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
@@ -339,28 +338,28 @@ get_type(const string &value)
 ObjectType
 get_description_type(const string &value)
 {
-    if ((value == "dods_das") | (value == "dods-das"))
+    if ((value == DAS1) || (value == "dods-das"))
         return dods_das;
-    else if ((value == "dods_dds") | (value == "dods-dds"))
+    else if ((value == "dods_dds") || (value == "dods-dds"))
         return dods_dds;
-    else if ((value == "dods_data") | (value == "dods-data"))
+    else if ((value == "dods_data") || (value == "dods-data"))
         return dods_data;
-    else if ((value == "dods_error") | (value == "dods-error"))
+    else if ((value == "dods_ddx") || (value == "dods-ddx"))
+        return dods_ddx;
+    else if ((value == "dods_data_ddx" || (value == "dods-data-ddx")))
+        return dods_data_ddx;
+    else if ((value == "dods_error") || (value == "dods-error"))
         return dods_error;
-    else if ((value == "web_error") | (value == "web-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"))
+
+    else if ((value == "dap4_dmr") || (value == "dap4-dmr") || (value == DMR_Content_Type))
+        return dap4_dmr;
+    else if ((value == "dap4_data") || (value == "dap4-data") || (value == DAP4_DATA_Content_Type))
         return dap4_data;
-    else if ((value == "dap4_error") | (value == "dap4-error"))
+    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;
 }
@@ -424,8 +423,8 @@ set_mime_text(ostream &strm, ObjectType type, const string &ver,
     else
         strm << rfc822_date(t).c_str() << CRLF ;
 
-    if (type == dap4_ddx)
-        strm << "Content-Type: text/xml" << CRLF ;
+    if (type == dap4_dmr)
+        strm << "Content-Type: application/vnd.org.opendap.dap4.dataset-metadata+xml" << CRLF ;
     else
         strm << "Content-Type: text/plain" << CRLF ;
 
@@ -461,8 +460,8 @@ void set_mime_text(ostream &strm, ObjectType type, EncodingType enc, const time_
 {
     strm << "HTTP/1.0 200 OK" << CRLF;
 
-    strm << "XDODS-Server: " << DVR<< CRLF;
-    strm << "XOPeNDAP-Server: " << DVR<< CRLF;
+    strm << "XDODS-Server: " << DVR << CRLF;
+    strm << "XOPeNDAP-Server: " << DVR << CRLF;
 
     if (protocol == "")
         strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF;
@@ -478,8 +477,8 @@ void set_mime_text(ostream &strm, ObjectType type, EncodingType enc, const time_
     else
         strm << rfc822_date(t).c_str() << CRLF;
 
-    if (type == dap4_ddx)
-        strm << "Content-Type: text/xml" << CRLF;
+    if (type == dap4_dmr)
+        strm << "Content-Type: application/vnd.org.opendap.dap4.dataset-metadata+xml" << CRLF;
     else
         strm << "Content-Type: text/plain" << CRLF;
 
@@ -696,7 +695,7 @@ void set_mime_binary(ostream &strm, ObjectType type, EncodingType enc, const tim
     strm << "XDODS-Server: " << DVR << CRLF;
     strm << "XOPeNDAP-Server: " << DVR << CRLF;
 
-    if (protocol == "")
+    if (protocol.empty())
         strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF;
     else
         strm << "XDAP: " << protocol << CRLF;
@@ -899,14 +898,16 @@ string get_next_mime_header(istream &in)
 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;
+    size_t length = header.length() + 1;
+    vector<char> s(length);
+    //char s[line_length];
+    iss.getline(&s[0], length, ':');
+    name = &s[0];
+
+    iss.ignore(length, ' ');
+    iss.getline(&s[0], length);
+    value = &s[0];
 
     downcase(name);
     downcase(value);
@@ -1001,13 +1002,13 @@ void read_multipart_headers(FILE *in, const string &content_type, const ObjectTy
 		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 + ".");
+				throw Error("Content-Type for this part of a DAP2 data ddx 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");
+						"Content-Description for this part of a DAP2 data ddx response must be dods-ddx or dods-data-ddx");
 		}
 		else if (name == "content-id") {
 			ci = true;
@@ -1038,8 +1039,7 @@ void read_multipart_headers(istream &in, const string &content_type, const Objec
 		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");
+				throw Error("Content-Description '" + value + "' not the expected value (expected: " + descrip[object_type] + ").");
 		}
 		else if (name == "content-id") {
 			ci = true;
@@ -1208,5 +1208,21 @@ remove_mime_header(FILE *in)
     return false;
 }
 
+/**
+ * Used for test code; strip the leading MIME headers from a response.
+ * @param in
+ */
+void
+remove_mime_header(istream &in)
+{
+	while(!get_next_mime_header(in).empty()) ;
+#if 0
+	string header;
+	do {
+		header = get_next_mime_header(in);
+	} while (!header.empty());
+#endif
+}
+
 } // namespace libdap
 
diff --git a/mime_util.h b/mime_util.h
index 4111660..c145c72 100644
--- a/mime_util.h
+++ b/mime_util.h
@@ -37,9 +37,7 @@
 #ifndef _mime_util_h
 #define _mime_util_h
 
-#ifndef _dds_h
-#include "DDS.h"
-#endif
+#include "media_types.h"	// Remove when the deprecated stuff comes out of the library. 11/12/13 jhrg
 
 #ifndef _object_type_h
 #include "ObjectType.h"
@@ -68,33 +66,36 @@ namespace libdap
     */
 
 //@{
-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);
+std::string rfc822_date(const time_t t);
+time_t last_modified_time(const std::string &name);
+ObjectType get_description_type(const std::string &value);
+bool is_boundary(const char *line, const std::string &boundary);
+std::string cid_to_header_value(const std::string &cid);
+
+std::string read_multipart_boundary(std::istream &in, const std::string &boundary = "");
 
-string read_multipart_boundary(istream &in, const string &boundary = "");
+void parse_mime_header(const std::string &header, std::string &name, std::string &value);
+std::string name_path(const std::string &path);
+std::string get_next_mime_header(std::istream &in);
 
-void parse_mime_header(const string &header, string &name, string &value);
-string name_path(const string &path);
-string get_next_mime_header(istream &in);
+void read_multipart_headers(std::istream &in, const std::string &content_type,
+	const ObjectType object_type, const std::string &cid = "");
 
-void read_multipart_headers(istream &in, const string &content_type,
-	const ObjectType object_type, const string &cid = "");
+// For testing only
+void remove_mime_header(std::istream &in);
 
 // All of these are deprecated
-string read_multipart_boundary(FILE *in, const string &boundary = "");
-void read_multipart_headers(FILE *in, const string &content_type,
-	const ObjectType object_type, const string &cid = "");
-bool do_version(const string &script_ver, const string &dataset_ver);
-void ErrMsgT(const string &Msgt);
-ObjectType get_type(const string &value);
+std::string read_multipart_boundary(FILE *in, const std::string &boundary = "");
+void read_multipart_headers(FILE *in, const std::string &content_type,
+	const ObjectType object_type, const std::string &cid = "");
+bool do_version(const std::string &script_ver, const std::string &dataset_ver);
+void ErrMsgT(const std::string &Msgt);
+ObjectType get_type(const std::string &value);
+std::string get_next_mime_header(FILE *in);
 bool remove_mime_header(FILE *in);
-string get_next_mime_header(FILE *in);
 
 #if 0
-bool found_override(string name, string &doc);
+bool found_override(std::string name, std::string &doc);
 #endif
 //@}
 
@@ -111,10 +112,10 @@ bool found_override(string name, string &doc);
 */
 //@{
 void set_mime_text(FILE *out, ObjectType type = unknown_type,
-                   const string &version = "", EncodingType enc = x_plain,
+                   const std::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,
+void set_mime_text(std::ostream &out, ObjectType type = unknown_type,
+                   const std::string &version = "", EncodingType enc = x_plain,
                    const time_t last_modified = 0);
 void set_mime_text(std::ostream &out, ObjectType type = unknown_type,
                    EncodingType enc = x_plain,
@@ -122,10 +123,10 @@ void set_mime_text(std::ostream &out, ObjectType type = unknown_type,
                    const std::string &protocol = "");
 
 void set_mime_html(FILE *out, ObjectType type = unknown_type,
-                   const string &version = "", EncodingType enc = x_plain,
+                   const std::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,
+void set_mime_html(std::ostream &out, ObjectType type = unknown_type,
+                   const std::string &version = "", EncodingType enc = x_plain,
                    const time_t last_modified = 0);
 void set_mime_html(std::ostream &out, ObjectType type = unknown_type,
                    EncodingType enc = x_plain,
@@ -133,19 +134,19 @@ void set_mime_html(std::ostream &out, ObjectType type = unknown_type,
                    const std::string &protocol = "");
 
 void set_mime_binary(FILE *out, ObjectType type = unknown_type,
-                     const string &version = "", EncodingType enc = x_plain,
+                     const std::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,
+void set_mime_binary(std::ostream &out, ObjectType type = unknown_type,
+                     const std::string &version = "", EncodingType enc = x_plain,
                      const time_t last_modified = 0);
 void set_mime_binary(std::ostream &out, ObjectType type = unknown_type,
                      EncodingType enc = x_plain,
                      const time_t last_modified = 0,
                      const std::string &protocol = "");
 
-void set_mime_multipart(ostream &out, const string &boundary,
-	const string &start, ObjectType type = unknown_type,
-        const string &version = "", EncodingType enc = x_plain,
+void set_mime_multipart(std::ostream &out, const std::string &boundary,
+	const std::string &start, ObjectType type = unknown_type,
+        const std::string &version = "", EncodingType enc = x_plain,
         const time_t last_modified = 0);
 
 void set_mime_multipart(std::ostream &out, const std::string &boundary,
@@ -153,23 +154,23 @@ void set_mime_multipart(std::ostream &out, const std::string &boundary,
 	const time_t last_modified = 0, const std::string &protocol = "",
 	const std::string &url = "");
 
-void set_mime_ddx_boundary(ostream &out, const string &boundary,
-	const string &start, ObjectType type = unknown_type,
+void set_mime_ddx_boundary(std::ostream &out, const std::string &boundary,
+	const std::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,
+void set_mime_data_boundary(std::ostream &out, const std::string &boundary,
+	const std::string &cid, ObjectType type = unknown_type,
         EncodingType enc = x_plain);
 
 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 = "");
+                    const std::string &reason = "Dataset not found",
+                    const std::string &version = "");
+void set_mime_error(std::ostream &out, int code = 404,
+                    const std::string &reason = "Dataset not found",
+                    const std::string &version = "");
 
 void set_mime_not_modified(FILE *out);
-void set_mime_not_modified(ostream &out);
+void set_mime_not_modified(std::ostream &out);
 
 
 //@}
diff --git a/parser-util.cc b/parser-util.cc
index dba8a00..4e4d5a5 100644
--- a/parser-util.cc
+++ b/parser-util.cc
@@ -51,6 +51,7 @@
 double w32strtod(const char *, char **);
 #endif
 
+#include "Error.h"
 #include "debug.h"
 #include "parser.h"             // defines constants such as ID_MAX
 #include "dods-limits.h"
@@ -252,7 +253,7 @@ int check_int32(const char *val)
         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 
+    // separate to highlight 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;
@@ -282,21 +283,57 @@ int check_uint32(const char *val)
         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
+	// 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;
+	}
+}
+
+unsigned long long get_ull(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 == '-')) {
+    	throw Error("The value '" + string(val) + "' is not a valid array index.");
+        // return FALSE;
+    }
+
+    char *ptr;
+    errno = 0;
+    unsigned long long v = strtoull(val, &ptr, 0);
+
+    if ((v == 0 && val == ptr) || *ptr != '\0') {
+    	throw Error("The value '" + string(val) + "' contains extra characters.");
+        //return FALSE;
+    }
+
     if (errno == ERANGE) {
-      return FALSE;
+    	throw Error("The value '" + string(val) + "' is out of range.");
+    	// return FALSE;
     }
-    // See above.
-    else if (v > DODS_UINT_MAX) {
-	return FALSE;
+    else if (v > DODS_MAX_ARRAY_INDEX) { // 2^61
+    	throw Error("The value '" + string(val) + "' is out of range.");
+    	// return FALSE;
     }
-    else {
-	return TRUE;
+	else {
+		return v;
     }
 }
 
+
 // Check first for system errors (like numbers so small they convert
 // (erroneously) to zero. Then make sure that the value is within
 // limits.
diff --git a/parser.h b/parser-util.h
similarity index 50%
copy from parser.h
copy to parser-util.h
index 5d1caea..80d246f 100644
--- a/parser.h
+++ b/parser-util.h
@@ -1,10 +1,9 @@
-
 // -*- 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.
+// Copyright (c) 2014 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -23,115 +22,11 @@
 //
 // 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
+#ifndef PARSER_UTIL_H_
+#define PARSER_UTIL_H_
 
-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);
-//@}
+namespace libdap {
 
 /** Given a string (<tt>const char *src</tt>), save it to the
     temporary variable pointed to by <tt>dst</tt>. If the string is
@@ -177,6 +72,8 @@ int check_uint16(const char *val);
 int check_int32(const char *val);
 int check_uint32(const char *val);
 
+unsigned long long get_ull(const char *val);
+
 /** Like <tt>check_byte()</tt> but for 64-bit float values.
 
     @brief Is the value a valid float? */
@@ -192,5 +89,4 @@ int check_url(const char *val);
 
 } // namespace libdap
 
-#endif // _parser_h
-
+#endif /* PARSER_UTIL_H_ */
diff --git a/parser.h b/parser.h
index 5d1caea..5da3638 100644
--- a/parser.h
+++ b/parser.h
@@ -133,64 +133,9 @@ 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
 
+#include "parser-util.h"
+
 #endif // _parser_h
 
diff --git a/tests/D4ResponseBuilder.cc b/tests/D4ResponseBuilder.cc
new file mode 100644
index 0000000..2f58ed6
--- /dev/null
+++ b/tests/D4ResponseBuilder.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) 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include <signal.h>
+#include <unistd.h>
+
+#include "DMR.h"
+#include "D4Group.h"
+#include "XMLWriter.h"
+#include "D4StreamMarshaller.h"
+#include "chunked_ostream.h"
+
+#include "D4ConstraintEvaluator.h"
+//#include "D4FunctionEvaluator.h"
+
+#include "mime_util.h"	// for last_modified_time() and rfc_822_date()
+#include "escaping.h"
+
+#ifndef WIN32
+#include "SignalHandler.h"
+#include "EventHandler.h"
+#include "AlarmHandler.h"
+#endif
+
+#include "D4ResponseBuilder.h"
+
+const std::string CRLF = "\r\n";             // Change here, expr-test.cc/dmr-test.cc
+
+using namespace std;
+using namespace libdap;
+
+void D4ResponseBuilder::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_timeout = 0;
+
+	d_default_protocol = "4.0"; // DAP_PROTOCOL_VERSION;
+}
+
+D4ResponseBuilder::~D4ResponseBuilder()
+{
+	// If an alarm was registered, delete it. The register code in SignalHandler
+	// always deletes the old alarm handler object, so only the one returned by
+	// remove_handler needs to be deleted at this point.
+	delete dynamic_cast<AlarmHandler*>(SignalHandler::instance()->remove_handler(SIGALRM));
+}
+
+/** Set the dataset name, which is a string used to access the dataset
+ * on the machine running the server. That is, this is typically a pathname
+ * to a data file, although it doesn't have to be. This is not
+ * echoed in error messages (because that would reveal server
+ * storage patterns that data providers might want to hide). All WWW-style
+ * escapes are replaced except for spaces.
+ *
+ * @brief Set the dataset pathname.
+ * @param ds The pathname (or equivalent) to the dataset.
+ */
+void D4ResponseBuilder::set_dataset_name(const string ds)
+{
+	d_dataset = www2id(ds, "%", "%20");
+}
+
+//// DAP4 methods follow
+
+/** Use values of this instance to establish a timeout alarm for the server.
+ If the timeout value is zero, do nothing.
+*/
+void D4ResponseBuilder::establish_timeout(ostream &stream) const
+{
+    if (d_timeout > 0) {
+        SignalHandler *sh = SignalHandler::instance();
+        EventHandler *old_eh = sh->register_handler(SIGALRM, new AlarmHandler(stream));
+        delete old_eh;
+        alarm(d_timeout);
+    }
+}
+
+void D4ResponseBuilder::remove_timeout() const
+{
+	alarm(0);
+}
+
+/**
+ * Write the on-the-wire DMR response.
+ *
+ * @note There is no timeout set on this reponse.
+ *
+ * @param out Write to this stream object
+ * @param dmr This is the DMR to write
+ * @param eval Use this ConstraintEvaluator
+ * @param with_mime_headers If true, include the MIME headers in the response
+ */
+void D4ResponseBuilder::send_dmr(ostream &out, DMR &dmr, bool with_mime_headers, bool constrained)
+{
+	if (with_mime_headers) set_mime_text(out, dap4_dmr, x_plain, last_modified_time(d_dataset), dmr.dap_version());
+
+	XMLWriter xml;
+	dmr.print_dap4(xml, constrained /* true == constrained */);
+	out << xml.get_doc() << flush;
+}
+
+void D4ResponseBuilder::send_dap(ostream &out, DMR &dmr, bool with_mime_headers, bool constrained)
+{
+	try {
+		// Set up the alarm.
+		establish_timeout(out);
+
+		if (dmr.response_limit() != 0 && dmr.request_size(true) > dmr.response_limit()) {
+			string msg = "The Request for " + long_to_string(dmr.request_size(true) / 1024)
+					+ "MB is too large; requests for this user are limited to "
+					+ long_to_string(dmr.response_limit() / 1024) + "MB.";
+			throw Error(msg);
+		}
+
+		if (with_mime_headers)
+			set_mime_binary(out, dap4_data, x_plain, last_modified_time(d_dataset), dmr.dap_version());
+
+	    // Write the DMR
+	    XMLWriter xml;
+	    dmr.print_dap4(xml, constrained);
+
+	    // now make the chunked output stream; set the size to be at least chunk_size
+	    // but make sure that the whole of the xml plus the CRLF can fit in the first
+	    // chunk. (+2 for the CRLF bytes).
+	    chunked_ostream cos(out, max((unsigned int)CHUNK_SIZE, xml.get_doc_size()+2));
+
+	    // using flush means that the DMR and CRLF are in the first chunk.
+	    cos << xml.get_doc() << CRLF << flush;
+
+	    // Write the data, chunked with checksums
+	    D4StreamMarshaller m(cos);
+	    dmr.root()->serialize(m, dmr, constrained);
+
+		out << flush;
+
+		remove_timeout();
+	}
+	catch (...) {
+		remove_timeout();
+		throw;
+	}
+}
diff --git a/tests/ResponseBuilder.h b/tests/D4ResponseBuilder.h
similarity index 59%
copy from tests/ResponseBuilder.h
copy to tests/D4ResponseBuilder.h
index 9cd5b65..69fb583 100644
--- a/tests/ResponseBuilder.h
+++ b/tests/D4ResponseBuilder.h
@@ -23,52 +23,62 @@
 //
 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
-#ifndef _response_builder_h
-#define _response_builder_h
+#ifndef _d4_response_builder_h
+#define _d4_response_builder_h
 
 #include <string>
 
-class libdap::ConstraintEvaluator;
-class libdap::DDS;
+namespace libdap {
+
+// class ConstraintEvaluator;
+class DDS;
+class DMR;
 
 /**
  * Used for testing only. This duplicates code in the bes/dap module.
  * jhrg 6/11/13
+ *
+ * This has now been extended with DAP4 DMR and Data response code.
+ * jhrg 9/5/13
  */
 
-class ResponseBuilder
+class D4ResponseBuilder
 {
-public:
-    friend class ResponseBuilderTest;
 
 protected:
     std::string d_dataset;  		/// Name of the dataset/database
-    std::string d_ce;  		    /// Constraint expression
-    std::string d_btp_func_ce;   /// The BTP functions, extracted from the CE
     int d_timeout;  		/// Response timeout after N seconds
     std::string d_default_protocol;	/// Version std::string for the library's default protocol version
 
     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();
-    }
+    D4ResponseBuilder() { initialize();  }
 
-    virtual ~ResponseBuilder();
+    virtual ~D4ResponseBuilder();
 
-    virtual std::string get_ce() const;
-    virtual void set_ce(std::string _ce);
+    /** 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.
 
-    virtual std::string get_dataset_name() const;
+     @brief Get the dataset name.
+     @return A string object that contains the name of the dataset. */
+    virtual std::string get_dataset_name() const { return d_dataset; }
     virtual void set_dataset_name(const std::string _dataset);
 
-    virtual void dataset_constraint(std::ostream &out, libdap::DDS &dds, libdap::ConstraintEvaluator &eval, bool ce_eval = true);
-    virtual void send_data(std::ostream &data_stream, libdap::DDS &dds, libdap::ConstraintEvaluator &eval, bool with_mime_headers = true);
+    // These are used for DAP4 testing by dmr-test.
+    virtual void establish_timeout(ostream &stream) const;
+    virtual void remove_timeout() const;
+
+    virtual void send_dmr(std::ostream &out, DMR &dmr, bool with_mime_headers, bool constrained);
+    virtual void send_dap(std::ostream &out, DMR &dmr, bool with_mime_headers, bool constrained);
 };
 
+} // namespace libdap
+
 #endif // _response_builder_h
diff --git a/tests/D4TestFunction.cc b/tests/D4TestFunction.cc
new file mode 100644
index 0000000..440da77
--- /dev/null
+++ b/tests/D4TestFunction.cc
@@ -0,0 +1,187 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 OPeNDAP, Inc.
+// Authors: Nathan Potter <npotter at opendap.org>
+//         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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include <BaseType.h>
+#include <TestFloat64.h>
+#include <TestStr.h>
+#include <TestArray.h>
+
+#include <Error.h>
+#include <DDS.h>
+
+#include "DMR.h"
+#include "D4RValue.h"
+
+#include <debug.h>
+#include <util.h>
+
+#include "D4TestFunction.h"
+
+namespace libdap {
+
+/**
+ * @brief scale a scalar or array variable
+ * This does not work for DAP2 Grids; only Array and scalar variables.
+ */
+void
+function_scale_dap2(int argc, BaseType * argv[], DDS &, BaseType **btpp)
+{
+    string info =
+    string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
+    "<function name=\"scale\" version=\"1.1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions\">\n" +
+    "</function>";
+
+    if (argc == 0) {
+        Str *response = new TestStr("info");
+        response->set_value(info);
+        *btpp = response;
+        return;
+    }
+
+    // Check for 2 arguments
+    DBG(cerr << "argc = " << argc << endl);
+    if (argc != 2)
+        throw Error(malformed_expr,"Wrong number of arguments to scale().");
+
+    double m = extract_double_value(argv[1]);
+
+    DBG(cerr << "m: " << m << << endl);
+
+    // Read the data, scale and return the result.
+    BaseType *dest = 0;
+    double *data;
+    if (argv[0]->is_vector_type()) {
+        TestArray &source = static_cast<TestArray&>(*argv[0]);
+        source.read();
+
+        data = extract_double_array(&source);
+        int length = source.length();
+        for (int i = 0; i < length; ++i)
+            data[i] = data[i] * m;
+
+        Array *result = new TestArray(source);
+
+        result->add_var_nocopy(new TestFloat64(source.name()));
+        result->set_value(data, length);
+
+        delete[] data; // set_value copies.
+
+        dest = result;
+    }
+    else if (argv[0]->is_simple_type() && !(argv[0]->type() == dods_str_c || argv[0]->type() == dods_url_c)) {
+    	argv[0]->read();
+        double data = extract_double_value(argv[0]);
+
+        data *= m;
+
+        Float64 *fdest = new TestFloat64(argv[0]->name());
+
+        fdest->set_value(data);
+        dest = fdest;
+    }
+    else {
+        throw Error(malformed_expr,"The scale() function works only for Arrays and scalars.");
+    }
+
+    *btpp = dest;
+    return;
+}
+
+/**
+ * @brief DAP4 scale a scalar or array variable
+ * This does not work for DAP2 Grids; only Array and scalar variables.
+ */
+BaseType *
+function_scale_dap4(D4RValueList *args, DMR &dmr)
+{
+    string info =
+    string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
+    "<function name=\"scale\" version=\"1.1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions\">\n" +
+    "</function>";
+
+    // DAP4 function porting information: in place of 'argc' use 'args.size()'
+    if (args->size() == 0) {
+        Str *response = new TestStr("info");
+        response->set_value(info);
+        // DAP4 function porting: return a BaseType* instead of using the value-result parameter
+        return response;
+    }
+
+    // Check for 2 arguments
+    DBG(cerr << "args.size() = " << args.size() << endl);
+    if (args->size() != 2)
+        throw Error(malformed_expr,"Wrong number of arguments to scale().");
+
+    // DAP4 function porting information: in place of 'argv[n]' use args->get_rvalue(n)->value(dmr)
+    // where 'n' is between 0 and args.size()-1. The line below is the DAP4 equivalent of 'argv[1].'
+    double m = extract_double_value(args->get_rvalue(1)->value(dmr));
+
+    DBG(cerr << "m: " << m << << endl);
+
+    // Read the data, scale and return the result.
+    //BaseType *dest = 0;
+    double *data;
+    BaseType *arg0 = args->get_rvalue(0)->value(dmr); // DAP4 function porting: ... 'argv[0]'
+    if (arg0->is_vector_type()) {
+        TestArray &source = static_cast<TestArray&>(*arg0);
+        source.read();
+
+        data = extract_double_array(&source);
+        int length = source.length();
+        for (int i = 0; i < length; ++i)
+            data[i] = data[i] * m;
+
+        Array *result = new TestArray(source);
+
+        result->add_var_nocopy(new TestFloat64(source.name()));
+        result->set_value(data, length);
+
+        delete[] data; // set_value copies.
+
+        // DAP4 function porting: return a BaseType* instead of using the value-result parameter
+        return result;
+    }
+    else if (arg0->is_simple_type() && !(arg0->type() == dods_str_c || arg0->type() == dods_url_c)) {
+    	arg0->read();
+        double data = extract_double_value(arg0);
+
+        data *= m;
+
+        Float64 *fdest = new TestFloat64(arg0->name());
+
+        fdest->set_value(data);
+        return fdest;
+    }
+    else {
+        throw Error(malformed_expr,"The scale() function works only for numerical arrays and scalars.");
+    }
+
+    return 0;
+}
+
+} // namesspace libdap
diff --git a/tests/D4TestFunction.h b/tests/D4TestFunction.h
new file mode 100644
index 0000000..b764193
--- /dev/null
+++ b/tests/D4TestFunction.h
@@ -0,0 +1,65 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 OPeNDAP, Inc.
+// Authors: Nathan Potter <npotter at opendap.org>
+//		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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <ServerFunction.h>
+
+namespace libdap {
+
+class BaseType;
+class DDS;
+class DMR;
+class D4RValueList;
+
+/**
+ * The scale() function scales data.
+ */
+void function_scale_dap2(int argc, BaseType *argv[], DDS &dds, BaseType **btpp);
+BaseType *function_scale_dap4(D4RValueList *args, DMR &dmr);
+
+/**
+ * The LinearScaleFunction class encapsulates the linear_scale function 'function_linear_scale'
+ * along with additional meta-data regarding its use and applicability.
+ */
+class D4TestFunction: public ServerFunction {
+public:
+	D4TestFunction()
+    {
+		setName("scale");
+		setDescriptionString("The scale() function is for testing.");
+		setUsageString("scale(var, num): scale var by num. var can be a scalar or an array");
+		setRole("http://services.opendap.org/dap4/server-side-function/scale");
+		setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions");
+		setFunction(function_scale_dap2);
+		setVersion("1.0");
+
+		setFunction(function_scale_dap4);
+    }
+    virtual ~D4TestFunction()
+    {
+    }
+};
+
+} // libdap namespace
diff --git a/tests/D4TestTypeFactory.cc b/tests/D4TestTypeFactory.cc
new file mode 100644
index 0000000..18b66d0
--- /dev/null
+++ b/tests/D4TestTypeFactory.cc
@@ -0,0 +1,252 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 "TestInt8.h"
+
+#include "TestInt16.h"
+#include "TestUInt16.h"
+#include "TestInt32.h"
+#include "TestUInt32.h"
+
+#include "TestInt64.h"
+#include "TestUInt64.h"
+
+#include "TestFloat32.h"
+#include "TestFloat64.h"
+
+#include "TestStr.h"
+#include "TestUrl.h"
+
+#include "TestD4Enum.h"
+
+#include "TestD4Opaque.h"
+
+#include "TestArray.h"
+#include "TestStructure.h"
+
+#include "TestD4Sequence.h"
+#include "TestD4Group.h"
+
+#include "D4TestTypeFactory.h"
+
+#include "debug.h"
+
+BaseType *D4TestTypeFactory::NewVariable(Type t, const string &name) const
+{
+	switch (t) {
+	case dods_byte_c:
+		return NewByte(name);
+	case dods_char_c:
+		return NewChar(name);
+
+	case dods_uint8_c:
+		return NewUInt8(name);
+	case dods_int8_c:
+		return NewInt8(name);
+
+	case dods_int16_c:
+		return NewInt16(name);
+	case dods_uint16_c:
+		return NewUInt16(name);
+	case dods_int32_c:
+		return NewInt32(name);
+	case dods_uint32_c:
+		return NewUInt32(name);
+
+	case dods_int64_c:
+		return NewInt64(name);
+	case dods_uint64_c:
+		return NewUInt64(name);
+
+	case dods_float32_c:
+		return NewFloat32(name);
+	case dods_float64_c:
+		return NewFloat64(name);
+
+	case dods_str_c:
+		return NewStr(name);
+	case dods_url_c:
+		return NewURL(name);
+
+	case dods_enum_c:
+		return NewEnum(name);
+
+	case dods_opaque_c:
+		return NewOpaque(name);
+
+	case dods_array_c:
+		return NewArray(name);
+
+	case dods_structure_c:
+		return NewStructure(name);
+
+	case dods_sequence_c:
+		return NewD4Sequence(name);
+
+	case dods_group_c:
+		return NewGroup(name);
+
+	default:
+		throw InternalErr(__FILE__, __LINE__, "Unimplemented type in DAP4.");
+	}
+}
+
+Byte *
+D4TestTypeFactory::NewByte(const string &n) const
+{
+	return new TestByte(n);
+}
+
+Byte *
+D4TestTypeFactory::NewChar(const string &n) const
+{
+	Byte *b = new TestByte(n);
+	b->set_type(dods_char_c);
+	return b;
+}
+
+Byte *
+D4TestTypeFactory::NewUInt8(const string &n) const
+{
+	Byte *b = new TestByte(n);
+	b->set_type(dods_uint8_c);
+	return b;
+}
+
+Int8 *
+D4TestTypeFactory::NewInt8(const string &n) const
+{
+	return new TestInt8(n);
+}
+
+Int16 *
+D4TestTypeFactory::NewInt16(const string &n) const
+{
+	return new TestInt16(n);
+}
+
+UInt16 *
+D4TestTypeFactory::NewUInt16(const string &n) const
+{
+	return new TestUInt16(n);
+}
+
+Int32 *
+D4TestTypeFactory::NewInt32(const string &n) const
+{
+	DBG(cerr << "Inside DAP4BaseTypeFactory::NewInt32" << endl);
+	return new TestInt32(n);
+}
+
+UInt32 *
+D4TestTypeFactory::NewUInt32(const string &n) const
+{
+	return new TestUInt32(n);
+}
+
+Int64 *
+D4TestTypeFactory::NewInt64(const string &n) const
+{
+	DBG(cerr << "Inside DAP4BaseTypeFactory::NewInt64" << endl);
+	return new TestInt64(n);
+}
+
+UInt64 *
+D4TestTypeFactory::NewUInt64(const string &n) const
+{
+	return new TestUInt64(n);
+}
+
+Float32 *
+D4TestTypeFactory::NewFloat32(const string &n) const
+{
+	return new TestFloat32(n);
+}
+
+Float64 *
+D4TestTypeFactory::NewFloat64(const string &n) const
+{
+	return new TestFloat64(n);
+}
+
+Str *
+D4TestTypeFactory::NewStr(const string &n) const
+{
+	return new TestStr(n);
+}
+
+Url *
+D4TestTypeFactory::NewUrl(const string &n) const
+{
+	return new TestUrl(n);
+}
+
+/** Note that this method is called NewURL - URL in caps.
+ */
+Url *
+D4TestTypeFactory::NewURL(const string &n) const
+{
+	return NewUrl(n);
+}
+
+D4Opaque *
+D4TestTypeFactory::NewOpaque(const string &n) const
+{
+	return new TestD4Opaque(n);
+}
+
+D4Enum *
+D4TestTypeFactory::NewEnum(const string &name, Type type) const
+{
+	return new TestD4Enum(name, type);
+}
+
+Array *
+D4TestTypeFactory::NewArray(const string &n, BaseType *v) const
+{
+	return new TestArray(n, v, true /* is_dap4 */);
+}
+
+Structure *
+D4TestTypeFactory::NewStructure(const string &n) const
+{
+	return new TestStructure(n);
+}
+
+D4Sequence *
+D4TestTypeFactory::NewD4Sequence(const string &n) const
+{
+	return new TestD4Sequence(n);
+}
+
+D4Group *
+D4TestTypeFactory::NewGroup(const string &n) const
+{
+	return new TestD4Group(n);
+}
+
diff --git a/D4BaseTypeFactory.h b/tests/D4TestTypeFactory.h
similarity index 63%
copy from D4BaseTypeFactory.h
copy to tests/D4TestTypeFactory.h
index b420f5a..4205671 100644
--- a/D4BaseTypeFactory.h
+++ b/tests/D4TestTypeFactory.h
@@ -4,7 +4,7 @@
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
 // Access Protocol.
 
-// Copyright (c) 2012 OPeNDAP, Inc.
+// Copyright (c) 2013 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -19,92 +19,63 @@
 //
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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 dap4_base_type_factory_h
-#define dap4_base_type_factory_h
+#ifndef d4_test_type_factory_h
+#define d4_test_type_factory_h
 
 #include <string>
 
-#include "BaseTypeFactory.h"
+#include "D4BaseTypeFactory.h"
 
-// Class declarations; Make sure to include the corresponding headers in the
-// implementation file.
+using namespace libdap ;
 
-namespace libdap
-{
-
-class Byte;
-class Int8;
-class Int16;
-class UInt16;
-class Int32;
-class UInt32;
-class Int64;
-class UInt64;
-
-class Float32;
-class Float64;
-
-class Str;
-class Url;
-
-class Array;
-class Structure;
-class Sequence;
-class Grid;
-
-class D4Group;
+/** A factory for the DAP4 TestByte, ...,  types.
+    @author James Gallagher */
+class D4TestTypeFactory : public D4BaseTypeFactory {
+public:
+    D4TestTypeFactory() {}
+    virtual ~D4TestTypeFactory() {}
 
-class BaseType;
+    virtual BaseTypeFactory *ptr_duplicate() const { return new D4TestTypeFactory; }
 
-/**
- *  Return instances of objects that are to be stored in a DDS for a
- *  DAP4 dataset.
- *
- */
-class D4BaseTypeFactory: public BaseTypeFactory
-{
-public:
-    D4BaseTypeFactory()
-    {}
-    virtual ~D4BaseTypeFactory()
-    {}
+    virtual BaseType *NewVariable(Type t, const string &name) const;
 
     virtual Byte *NewByte(const string &n = "") const;
+
+    // New for DAP4
     virtual Int8 *NewInt8(const string &n = "") const;
     virtual Byte *NewUInt8(const string &n = "") const;
+    virtual Byte *NewChar(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;
 
+    // New for DAP4
     virtual Int64 *NewInt64(const string &n = "") const;
     virtual UInt64 *NewUInt64(const string &n = "") const;
 
     virtual Float32 *NewFloat32(const string &n = "") const;
     virtual Float64 *NewFloat64(const string &n = "") const;
 
+    virtual D4Enum *NewEnum(const string &n = "", Type type = dods_null_c) const;
+
     virtual Str *NewStr(const string &n = "") const;
     virtual Url *NewUrl(const string &n = "") const;
     virtual Url *NewURL(const string &n = "") const;
 
-    // FIXME Define these
-#if 0
-    virtual Opaque *NewOpaque(const string &n = "") const;
-    virtual Enumeration *NewEnumeration(const string &n = "") const;
-#endif
+    virtual D4Opaque *NewOpaque(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;
-#if 1
+    virtual D4Sequence *NewD4Sequence(const string &n = "") const;
+
     virtual D4Group *NewGroup(const string &n = "") const;
-#endif
-    virtual Array *NewArray(const string &n = "", BaseType *v = 0) const;
-    virtual Grid *NewGrid(const string &n = "") const;
 };
 
-} // namespace libdap
-
-#endif // dap4_base_type_factory_h
+#endif // d4_test_type_factory_h
diff --git a/tests/DASTest b/tests/DASTest
index 2da5e9e..fd4ae99 100755
--- a/tests/DASTest
+++ b/tests/DASTest
@@ -941,7 +941,7 @@ fi
 # List of tests.
 if $at_list_p; then
   cat <<_ATEOF || at_write_fail=1
-libdap 3.12.0 test suite: das-test test groups:
+libdap 3.14.0 test suite: das-test test groups:
 
  NUM: FILE-NAME:LINE     TEST-GROUP-NAME
       KEYWORDS
@@ -982,7 +982,7 @@ _ATEOF
   exit $at_write_fail
 fi
 if $at_version_p; then
-  $as_echo "$as_me (libdap 3.12.0)" &&
+  $as_echo "$as_me (libdap 3.14.0)" &&
   cat <<\_ATEOF || at_write_fail=1
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1159,11 +1159,11 @@ exec 5>>"$at_suite_log"
 
 # Banners and logs.
 $as_echo "## ----------------------------------- ##
-## libdap 3.12.0 test suite: das-test. ##
+## libdap 3.14.0 test suite: das-test. ##
 ## ----------------------------------- ##"
 {
   $as_echo "## ----------------------------------- ##
-## libdap 3.12.0 test suite: das-test. ##
+## libdap 3.14.0 test suite: das-test. ##
 ## ----------------------------------- ##"
   echo
 
@@ -2007,7 +2007,7 @@ _ASBOX
   $as_echo "Please send $at_msg and all information you think might help:
 
    To: <opendap-tech at opendap.org>
-   Subject: [libdap 3.12.0] $as_me: $at_fail_list${at_fail_list:+ failed${at_xpass_list:+, }}$at_xpass_list${at_xpass_list:+ passed unexpectedly}
+   Subject: [libdap 3.14.0] $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
diff --git a/tests/DDSTest b/tests/DDSTest
index 2d20b0a..e729251 100755
--- a/tests/DDSTest
+++ b/tests/DDSTest
@@ -930,7 +930,7 @@ fi
 # List of tests.
 if $at_list_p; then
   cat <<_ATEOF || at_write_fail=1
-libdap 3.12.0 test suite: dds-test test groups:
+libdap 3.14.0 test suite: dds-test test groups:
 
  NUM: FILE-NAME:LINE     TEST-GROUP-NAME
       KEYWORDS
@@ -971,7 +971,7 @@ _ATEOF
   exit $at_write_fail
 fi
 if $at_version_p; then
-  $as_echo "$as_me (libdap 3.12.0)" &&
+  $as_echo "$as_me (libdap 3.14.0)" &&
   cat <<\_ATEOF || at_write_fail=1
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1148,11 +1148,11 @@ exec 5>>"$at_suite_log"
 
 # Banners and logs.
 $as_echo "## ----------------------------------- ##
-## libdap 3.12.0 test suite: dds-test. ##
+## libdap 3.14.0 test suite: dds-test. ##
 ## ----------------------------------- ##"
 {
   $as_echo "## ----------------------------------- ##
-## libdap 3.12.0 test suite: dds-test. ##
+## libdap 3.14.0 test suite: dds-test. ##
 ## ----------------------------------- ##"
   echo
 
@@ -1996,7 +1996,7 @@ _ASBOX
   $as_echo "Please send $at_msg and all information you think might help:
 
    To: <opendap-tech at opendap.org>
-   Subject: [libdap 3.12.0] $as_me: $at_fail_list${at_fail_list:+ failed${at_xpass_list:+, }}$at_xpass_list${at_xpass_list:+ passed unexpectedly}
+   Subject: [libdap 3.14.0] $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
diff --git a/tests/DMRTest b/tests/DMRTest
new file mode 100755
index 0000000..f148689
--- /dev/null
+++ b/tests/DMRTest
@@ -0,0 +1,10475 @@
+#! /bin/sh
+# Generated from DMRTest.at by GNU Autoconf 2.69.
+#
+# Copyright (C) 2009-2012 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.
+as_myself=
+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
+test -x / || 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 :
+  export CONFIG_SHELL
+             # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+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_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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 to rerun failed tests.
+at_recheck=
+# 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
+
+# Whether to enable colored test results.
+at_color=no
+# List of the tested programs.
+at_tested=''
+# 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;DMRTest.at:128;parse dmr-testsuite/test_simple_1.xml;parse;
+2;DMRTest.at:129;parse dmr-testsuite/test_simple_2.xml;parse;
+3;DMRTest.at:130;parse dmr-testsuite/test_simple_3.xml;parse;
+4;DMRTest.at:132;parse dmr-testsuite/test_simple_3_error_1.xml;parse;
+5;DMRTest.at:133;parse dmr-testsuite/test_simple_3_error_2.xml;parse;
+6;DMRTest.at:134;parse dmr-testsuite/test_simple_3_error_3.xml;parse;
+7;DMRTest.at:136;parse dmr-testsuite/test_simple_4.xml;parse;
+8;DMRTest.at:137;parse dmr-testsuite/test_simple_5.xml;parse;
+9;DMRTest.at:138;parse dmr-testsuite/test_simple_6.xml;parse;
+10;DMRTest.at:139;parse dmr-testsuite/test_simple_7.xml;parse;
+11;DMRTest.at:140;parse dmr-testsuite/test_simple_8.xml;parse;
+12;DMRTest.at:141;parse dmr-testsuite/test_simple_9.xml;parse;
+13;DMRTest.at:142;parse dmr-testsuite/test_simple_9.1.xml;parse;
+14;DMRTest.at:143;parse dmr-testsuite/test_simple_10.xml;parse;
+15;DMRTest.at:145;parse dmr-testsuite/test_array_1.xml;parse;
+16;DMRTest.at:146;parse dmr-testsuite/test_array_2.xml;parse;
+17;DMRTest.at:147;parse dmr-testsuite/test_array_3.xml;parse;
+18;DMRTest.at:148;parse dmr-testsuite/test_array_4.xml;parse;
+19;DMRTest.at:149;parse dmr-testsuite/test_array_5.xml;parse;
+20;DMRTest.at:150;parse dmr-testsuite/test_array_6.xml;parse;
+21;DMRTest.at:151;parse dmr-testsuite/test_array_7.xml;parse;
+22;DMRTest.at:152;parse dmr-testsuite/test_array_8.xml;parse;
+23;DMRTest.at:153;parse dmr-testsuite/test_array_10.xml;parse;
+24;DMRTest.at:154;parse dmr-testsuite/test_array_11.xml;parse;
+25;DMRTest.at:158;trans/receive dmr-testsuite/test_simple_1.xml;trans;
+26;DMRTest.at:159;trans/receive dmr-testsuite/test_simple_2.xml;trans;
+27;DMRTest.at:160;trans/receive dmr-testsuite/test_simple_3.xml;trans;
+28;DMRTest.at:161;trans/receive dmr-testsuite/test_simple_4.xml;trans;
+29;DMRTest.at:162;trans/receive dmr-testsuite/test_simple_5.xml;trans;
+30;DMRTest.at:163;trans/receive dmr-testsuite/test_simple_6.xml;trans;
+31;DMRTest.at:164;trans/receive dmr-testsuite/test_simple_7.xml;trans;
+32;DMRTest.at:165;trans/receive dmr-testsuite/test_simple_8.xml;trans;
+33;DMRTest.at:166;trans/receive dmr-testsuite/test_simple_9.xml;trans;
+34;DMRTest.at:167;trans/receive dmr-testsuite/test_simple_9.1.xml;trans;
+35;DMRTest.at:168;trans/receive dmr-testsuite/test_simple_10.xml;trans;
+36;DMRTest.at:170;trans/receive dmr-testsuite/test_array_1.xml;trans;
+37;DMRTest.at:171;trans/receive dmr-testsuite/test_array_2.xml;trans;
+38;DMRTest.at:172;trans/receive dmr-testsuite/test_array_3.xml;trans;
+39;DMRTest.at:173;trans/receive dmr-testsuite/test_array_4.xml;trans;
+40;DMRTest.at:174;trans/receive dmr-testsuite/test_array_5.xml;trans;
+41;DMRTest.at:175;trans/receive dmr-testsuite/test_array_6.xml;trans;
+42;DMRTest.at:176;trans/receive dmr-testsuite/test_array_7.xml;trans;
+43;DMRTest.at:177;trans/receive dmr-testsuite/test_array_8.xml;trans;
+44;DMRTest.at:178;trans/receive dmr-testsuite/test_array_10.xml;trans;
+45;DMRTest.at:179;trans/receive dmr-testsuite/test_array_11.xml;trans;
+46;DMRTest.at:181;intern data dmr-testsuite/test_simple_1.xml;intern;
+47;DMRTest.at:182;intern data dmr-testsuite/test_simple_2.xml;intern;
+48;DMRTest.at:183;intern data dmr-testsuite/test_simple_3.xml;intern;
+49;DMRTest.at:184;intern data dmr-testsuite/test_simple_4.xml;intern;
+50;DMRTest.at:185;intern data dmr-testsuite/test_simple_5.xml;intern;
+51;DMRTest.at:186;intern data dmr-testsuite/test_simple_6.xml;intern;
+52;DMRTest.at:187;intern data dmr-testsuite/test_simple_7.xml;intern;
+53;DMRTest.at:188;intern data dmr-testsuite/test_simple_8.xml;intern;
+54;DMRTest.at:189;intern data dmr-testsuite/test_simple_9.xml;intern;
+55;DMRTest.at:190;intern data dmr-testsuite/test_simple_9.1.xml;intern;
+56;DMRTest.at:191;intern data dmr-testsuite/test_simple_10.xml;intern;
+57;DMRTest.at:193;intern data dmr-testsuite/test_array_1.xml;intern;
+58;DMRTest.at:194;intern data dmr-testsuite/test_array_2.xml;intern;
+59;DMRTest.at:195;intern data dmr-testsuite/test_array_3.xml;intern;
+60;DMRTest.at:196;intern data dmr-testsuite/test_array_4.xml;intern;
+61;DMRTest.at:197;intern data dmr-testsuite/test_array_5.xml;intern;
+62;DMRTest.at:198;intern data dmr-testsuite/test_array_6.xml;intern;
+63;DMRTest.at:199;intern data dmr-testsuite/test_array_7.xml;intern;
+64;DMRTest.at:200;intern data dmr-testsuite/test_array_8.xml;intern;
+65;DMRTest.at:201;intern data dmr-testsuite/test_array_10.xml;intern;
+66;DMRTest.at:202;intern data dmr-testsuite/test_array_11.xml;intern;
+67;DMRTest.at:206;trans/receive dmr-testsuite/test_array_4.xml a;trans;
+68;DMRTest.at:207;trans/receive dmr-testsuite/test_array_4.xml a[][] ;trans;
+69;DMRTest.at:209;trans/receive dmr-testsuite/test_array_4.xml /row=[0:1];/col=[3];a;trans;
+70;DMRTest.at:211;trans/receive dmr-testsuite/test_array_4.xml /row=[0:1];/col=[3];a[][] ;trans;
+71;DMRTest.at:213;trans/receive dmr-testsuite/test_array_4.xml /row=[0:1];/col=[3];a[][];b[0][];c[0:][0:] ;trans;
+72;DMRTest.at:215;trans/receive dmr-testsuite/test_array_4.xml x[][] ;trans;
+73;DMRTest.at:216;trans/receive dmr-testsuite/test_array_4.xml /row=[0:1];x[][] ;trans;
+74;DMRTest.at:218;trans/receive dmr-testsuite/test_array_4.xml c[2:][2:] ;trans;
+75;DMRTest.at:220;trans/receive dmr-testsuite/test_simple_6.xml s;trans;
+76;DMRTest.at:221;trans/receive dmr-testsuite/test_simple_6.xml s.i1;trans;
+77;DMRTest.at:222;trans/receive dmr-testsuite/test_simple_6.xml s.s;trans;
+78;DMRTest.at:223;trans/receive dmr-testsuite/test_simple_6.1.xml s.inner.i2;trans;
+79;DMRTest.at:225;trans/receive dmr-testsuite/test_simple_6.xml s{i1};trans;
+80;DMRTest.at:226;trans/receive dmr-testsuite/test_simple_6.xml s{s};trans;
+81;DMRTest.at:227;trans/receive dmr-testsuite/test_simple_6.1.xml s{inner.i2};trans;
+82;DMRTest.at:228;trans/receive dmr-testsuite/test_simple_6.1.xml s{inner{i2}};trans;
+83;DMRTest.at:231;trans/receive dmr-testsuite/test_array_6.xml a;trans;
+84;DMRTest.at:232;trans/receive dmr-testsuite/test_array_6.xml a[][] ;trans;
+85;DMRTest.at:233;trans/receive dmr-testsuite/test_array_6.xml /row=[0:1];a[][] ;trans;
+86;DMRTest.at:234;trans/receive dmr-testsuite/test_array_6.xml /row=[0:1];a[][1:2] ;trans;
+87;DMRTest.at:237;trans/receive dmr-testsuite/test_array_6.2.xml a;trans;
+88;DMRTest.at:238;trans/receive dmr-testsuite/test_array_6.2.xml a{i;j};trans;
+89;DMRTest.at:239;trans/receive dmr-testsuite/test_array_6.2.xml a.i;trans;
+90;DMRTest.at:240;trans/receive dmr-testsuite/test_array_6.2.xml a{i};trans;
+91;DMRTest.at:241;trans/receive dmr-testsuite/test_array_6.2.xml a.i[0][1:2] ;trans;
+92;DMRTest.at:242;trans/receive dmr-testsuite/test_array_6.2.xml a{i[0][1:2]} ;trans;
+93;DMRTest.at:243;trans/receive dmr-testsuite/test_array_6.2.xml /row=[0:1];a.i[][1:2] ;trans;
+94;DMRTest.at:244;trans/receive dmr-testsuite/test_array_6.2.xml /row=[0:1];a{i[][1:2]} ;trans;
+95;DMRTest.at:246;trans/receive dmr-testsuite/test_array_6.2.xml a.j;trans;
+96;DMRTest.at:249;trans/receive dmr-testsuite/test_array_6.1.xml a;trans;
+97;DMRTest.at:252;trans/receive dmr-testsuite/test_array_6.1.xml /row=[1:2];a[][0] ;trans;
+98;DMRTest.at:253;trans/receive dmr-testsuite/test_array_6.1.xml /row=[1:2];a[][0]{i;j} ;trans;
+99;DMRTest.at:255;trans/receive dmr-testsuite/test_array_6.1.xml row=[1:2];a[][0]{i;j} ;trans;
+100;DMRTest.at:258;trans/receive dmr-testsuite/test_array_6.1.xml a{i[1:2][1:3];j} ;trans;
+101;DMRTest.at:259;trans/receive dmr-testsuite/test_array_6.1.xml a[][]{i[1:2][1:3];j} ;trans;
+102;DMRTest.at:263;trans/receive dmr-testsuite/test_array_6.1.xml /row=[1];a[][0]{i[][0:1]} ;trans;
+103;DMRTest.at:266;trans/receive dmr-testsuite/test_simple_7.xml s;trans;
+104;DMRTest.at:267;trans/receive dmr-testsuite/test_simple_7.xml s{i1;s};trans;
+105;DMRTest.at:269;trans/receive dmr-testsuite/test_simple_7.xml s.i1;trans;
+106;DMRTest.at:270;trans/receive dmr-testsuite/test_simple_7.xml s{i1};trans;
+107;DMRTest.at:272;trans/receive dmr-testsuite/test_simple_8.xml outer;trans;
+108;DMRTest.at:273;trans/receive dmr-testsuite/test_simple_8.xml outer.s.s;trans;
+109;DMRTest.at:274;trans/receive dmr-testsuite/test_simple_8.xml outer{s{s}};trans;
+110;DMRTest.at:276;trans/receive dmr-testsuite/test_array_7.xml s;trans;
+111;DMRTest.at:277;trans/receive dmr-testsuite/test_array_7.xml s{i1;s};trans;
+112;DMRTest.at:279;trans/receive dmr-testsuite/test_array_7.xml s.i1;trans;
+113;DMRTest.at:280;trans/receive dmr-testsuite/test_array_7.xml s{i1};trans;
+114;DMRTest.at:282;trans/receive dmr-testsuite/test_array_7.xml s[1] ;trans;
+115;DMRTest.at:283;trans/receive dmr-testsuite/test_array_7.xml s[1]{i1;s};trans;
+116;DMRTest.at:285;trans/receive dmr-testsuite/test_array_7.xml s[1]{i1};trans;
+117;DMRTest.at:288;trans/receive dmr-testsuite/test_array_8.xml /col=[1:2];s[1][]{i1};trans;
+118;DMRTest.at:289;trans/receive dmr-testsuite/test_array_8.xml col=[1:2];s[1][]{i1};trans;
+119;DMRTest.at:292;trans/receive dmr-testsuite/test_array_7.1.xml ;trans;
+120;DMRTest.at:293;trans/receive dmr-testsuite/test_array_7.1.xml s;trans;
+121;DMRTest.at:295;trans/receive dmr-testsuite/test_array_7.1.xml s.i1;trans;
+122;DMRTest.at:296;trans/receive dmr-testsuite/test_array_7.1.xml s.i1[][] ;trans;
+123;DMRTest.at:297;trans/receive dmr-testsuite/test_array_7.1.xml s{i1};trans;
+124;DMRTest.at:298;trans/receive dmr-testsuite/test_array_7.1.xml s{i1[][]} ;trans;
+125;DMRTest.at:300;trans/receive dmr-testsuite/test_array_7.1.xml s.i1[0][0] ;trans;
+126;DMRTest.at:301;trans/receive dmr-testsuite/test_array_7.1.xml s{i1[0][0]} ;trans;
+127;DMRTest.at:303;trans/receive dmr-testsuite/test_array_7.1.xml s.i1[0:2][1:2] ;trans;
+128;DMRTest.at:307;trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s ;trans;
+129;DMRTest.at:309;trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s.i1 ;trans;
+130;DMRTest.at:310;trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s.i1[][] ;trans;
+131;DMRTest.at:311;trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s{i1} ;trans;
+132;DMRTest.at:312;trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s{i1[][]} ;trans;
+133;DMRTest.at:315;trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[]{i1};trans;
+134;DMRTest.at:316;trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[]{i1[][]};trans;
+135;DMRTest.at:317;trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s{i1[][]};trans;
+136;DMRTest.at:319;trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[]{i1[0][]};trans;
+137;DMRTest.at:320;trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s{i1[0][]};trans;
+138;DMRTest.at:322;trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[0]{i1};trans;
+139;DMRTest.at:323;trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[0]{i1[][]};trans;
+140;DMRTest.at:325;trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[0]{i1[0][]};trans;
+141;DMRTest.at:329;trans/receive dmr-testsuite/test_array_1.xml scale(x,1) ;trans;
+142;DMRTest.at:330;trans/receive dmr-testsuite/test_array_1.xml scale(x,10) ;trans;
+143;DMRTest.at:331;trans/receive dmr-testsuite/test_array_1.xml scale(x,-10) ;trans;
+144;DMRTest.at:332;trans/receive dmr-testsuite/test_array_1.xml scale(x,0.001) ;trans;
+145;DMRTest.at:333;trans/receive dmr-testsuite/test_array_1.xml scale(x,-0.001) ;trans;
+146;DMRTest.at:337;trans/receive dmr-testsuite/test_array_1.xml scale(x,0x7fffffffffffffff) ;trans;
+147;DMRTest.at:339;trans/receive dmr-testsuite/test_array_1.xml scale(x,0x8fffffffffffffff) ;trans;
+148;DMRTest.at:343;trans/receive dmr-testsuite/test_array_5.xml scale(a,0.001) ;trans;
+149;DMRTest.at:344;trans/receive dmr-testsuite/test_array_5.xml scale(b,0.001) ;trans;
+150;DMRTest.at:346;trans/receive dmr-testsuite/test_array_5.xml scale(c,0.001) ;trans;
+151;DMRTest.at:347;trans/receive dmr-testsuite/test_array_5.xml scale(d,0.001) ;trans;
+152;DMRTest.at:352;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(u,10) ;trans;
+153;DMRTest.at:353;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(u,v) ;trans;
+154;DMRTest.at:354;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(scale(u,10),0.01) ;trans;
+155;DMRTest.at:357;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(Point.x,10) ;trans;
+156;DMRTest.at:358;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(Point.x,Point.y) ;trans;
+157;DMRTest.at:359;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(scale(Point.x,10),0.01) ;trans;
+158;DMRTest.at:362;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Byte(20:1,2,3,4),10) ;trans;
+159;DMRTest.at:363;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Int8(20:10,11,12,-9),10) ;trans;
+160;DMRTest.at:364;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$UInt16(20:1,2,3,4),10) ;trans;
+161;DMRTest.at:365;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Int16(20:1,2,3,-4),10) ;trans;
+162;DMRTest.at:366;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$UInt32(20:1,2,3,4),10) ;trans;
+163;DMRTest.at:367;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Int32(20:1,2,3,-4),10) ;trans;
+164;DMRTest.at:368;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$UInt64(20:1,2,3,0xffffffffffffffff),1) ;trans;
+165;DMRTest.at:369;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Int64(20:1,2,3,0x7fffffffffffffff),1) ;trans;
+166;DMRTest.at:370;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Float32(20:1,2,3,4.55),10) ;trans;
+167;DMRTest.at:371;trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Float64(20:1,2,3,4.55),10) ;trans;
+168;DMRTest.at:375;trans/receive dmr-testsuite/vol_1_ce_10.xml scale(lat,10) ;trans;
+169;DMRTest.at:376;trans/receive dmr-testsuite/vol_1_ce_10.xml scale(lat,10);scale(lon,10) ;trans;
+170;DMRTest.at:377;trans/receive dmr-testsuite/vol_1_ce_10.xml scale(lat,10);scale(lon,10) lat[10:11][10:11];lon[10:11][10:11];trans;
+"
+# List of the all the test groups.
+at_groups_all=`$as_echo "$at_help_all" | sed 's/;.*//'`
+
+# 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 170; 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
+}
+
+##
+## Set up package specific options.
+##
+
+at_arg_given_generate_parse=false
+
+at_arg_given_generate_trans=false
+
+at_arg_given_generate_trans_ce=false
+
+
+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" : '[^=]*=\(.*\)'` ;;
+  *)    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=:
+	;;
+
+    --color )
+	at_color=always
+	;;
+    --color=* )
+	case $at_optarg in
+	no | never | none) at_color=never ;;
+	auto | tty | if-tty) at_color=auto ;;
+	always | yes | force) at_color=always ;;
+	*) at_optname=`echo " $at_option" | sed 's/^ //; s/=.*//'`
+	   as_fn_error $? "unrecognized argument to $at_optname: $at_optarg" ;;
+	esac
+	;;
+
+    --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$as_nl"
+	;;
+
+    # 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 -ne '/^'$at_range_start'$/,$p'`
+	as_fn_append at_groups "$at_range$as_nl"
+	;;
+
+    -[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 -ne '1,/^'$at_range_end'$/p'`
+	as_fn_append at_groups "$at_range$as_nl"
+	;;
+
+    [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 -ne '/^'$at_range_start'$/,/^'$at_range_end'$/p'`
+	as_fn_append at_groups "$at_range$as_nl"
+	;;
+
+    # Directory selection.
+    --directory | -C )
+	at_prev=--directory
+	;;
+    --directory=* )
+	at_change_dir=:
+	at_dir=$at_optarg
+	if test x- = "x$at_dir" ; then
+	  at_dir=./-
+	fi
+	;;
+
+    # 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 keywords.
+	at_groups_selected=`$as_echo "$at_groups_selected" | sed 's/;.*//'`
+	as_fn_append at_groups "$at_groups_selected$as_nl"
+	;;
+    --recheck)
+	at_recheck=:
+	;;
+    --generate_parse )
+	at_prev=--generate_parse
+	;;
+    --generate_parse=* )
+	at_arg_generate_parse=$at_optarg
+	at_arg_given_generate_parse=:
+	echo "./dmr-test -x -p $at_arg_generate_parse > $at_arg_generate_parse.baseline 2>&1";
+     ./dmr-test -x -p $at_arg_generate_parse > $at_arg_generate_parse.baseline 2>&1;
+     echo "Built baseline for $at_arg_generate_parse";
+     exit
+	;;
+
+    --generate_trans )
+	at_prev=--generate_trans
+	;;
+    --generate_trans=* )
+	at_arg_generate_trans=$at_optarg
+	at_arg_given_generate_trans=:
+	echo "./dmr-test -x -t $at_arg_generate_trans > $at_arg_generate_trans.trans_base 2>&1";
+     ./dmr-test -x -t $at_arg_generate_trans > $at_arg_generate_trans.trans_base 2>&1;
+     echo "Built baseline for $at_arg_generate_trans";
+     exit
+	;;
+
+    --generate_trans_ce )
+	at_prev=--generate_trans_ce
+	;;
+    --generate_trans_ce=* )
+	at_arg_generate_trans_ce=$at_optarg
+	at_arg_given_generate_trans_ce=:
+	data=`echo $at_arg_generate_trans_ce | sed 's@\(.*\),\(.*\),\(.*\)@\1 at g'`
+     ce=`echo $at_arg_generate_trans_ce | sed 's@\(.*\),\(.*\),\(.*\)@\2 at g'`
+     code=`echo $at_arg_generate_trans_ce | sed 's@\(.*\),\(.*\),\(.*\)@\3 at g'`
+     echo "./dmr-test -x -t $data -c $ce > $data.$code.trans_base 2>&1";
+     ./dmr-test -x -t $data -c "$ce" > $data.$code.trans_base 2>&1;
+     echo "Built baseline for $at_arg_generate_trans_ce";
+     exit
+	;;
+
+
+    *=*)
+	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
+
+# The file containing the suite.
+at_suite_log=$at_dir/$as_me.log
+
+# Selected test groups.
+if test -z "$at_groups$at_recheck"; then
+  at_groups=$at_groups_all
+else
+  if test -n "$at_recheck" && test -r "$at_suite_log"; then
+    at_oldfails=`sed -n '
+      /^Failed tests:$/,/^Skipped tests:$/{
+	s/^[ ]*\([1-9][0-9]*\):.*/\1/p
+      }
+      /^Unexpected passes:$/,/^## Detailed failed tests/{
+	s/^[ ]*\([1-9][0-9]*\):.*/\1/p
+      }
+      /^## Detailed failed tests/q
+      ' "$at_suite_log"`
+    as_fn_append at_groups "$at_oldfails$as_nl"
+  fi
+  # Sort the tests, removing duplicates.
+  at_groups=`$as_echo "$at_groups" | sort -nu | sed '/^$/d'`
+fi
+
+if test x"$at_color" = xalways \
+   || { test x"$at_color" = xauto && test -t 1; }; then
+  at_red=`printf '\033[0;31m'`
+  at_grn=`printf '\033[0;32m'`
+  at_lgn=`printf '\033[1;32m'`
+  at_blu=`printf '\033[1;34m'`
+  at_std=`printf '\033[m'`
+else
+  at_red= at_grn= at_lgn= at_blu= at_std=
+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
+      --color[=never|auto|always]
+                 enable colored test results on terminal, or always
+  -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
+      --recheck  select all tests that failed or passed unexpectedly last time
+  -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
+
+Other options:
+_ATEOF
+
+cat <<_ATEOF || at_write_fail=1
+--generate_parse=arg   Build the baseline file for parser test 'arg'
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+--generate_trans=arg  Build the baseline file for round trip transmission test 'arg'
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+--generate_trans_ce=dataset,ce,ext  Build the baseline (ext) file for round trip transmission test 'arg' with 'ce'
+_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.14.0 test suite: dmr-test test groups:
+
+ NUM: FILE-NAME:LINE     TEST-GROUP-NAME
+      KEYWORDS
+
+_ATEOF
+  # Pass an empty line as separator between selected groups and help.
+  $as_echo "$at_groups$as_nl$as_nl$at_help_all" |
+    awk 'NF == 1 && FS != ";" {
+	   selected[$ 1] = 1
+	   next
+	 }
+	 /^$/ { FS = ";" }
+	 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.14.0)" &&
+  cat <<\_ATEOF || at_write_fail=1
+
+Copyright (C) 2012 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?  Yes if more than one test is run.
+case $at_groups in #(
+  *$as_nl* )
+      at_print_banners=: ;; #(
+  * ) at_print_banners=false ;;
+esac
+# Text for banner N, set to a single space once printed.
+
+# Take any -C into account.
+if $at_change_dir ; then
+  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_dir might have changed since earlier).
+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.
+$as_echo "## ----------------------------------- ##
+## libdap 3.14.0 test suite: dmr-test. ##
+## ----------------------------------- ##"
+{
+  $as_echo "## ----------------------------------- ##
+## libdap 3.14.0 test suite: dmr-test. ##
+## ----------------------------------- ##"
+  echo
+
+  $as_echo "$as_me: command line was:"
+  $as_echo "  \$ $0 $at_cli_args"
+  echo
+
+  # If ChangeLog exists, list a few lines in case it might help determining
+  # the exact version.
+  if test -n "$at_top_srcdir" && test -f "$at_top_srcdir/ChangeLog"; then
+    $as_echo "## ---------- ##
+## ChangeLog. ##
+## ---------- ##"
+    echo
+    sed 's/^/| /;10q' "$at_top_srcdir/ChangeLog"
+    echo
+  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=\" \""
+  if test -z "$at_banner_text"; then
+    $at_first || echo
+  else
+    $as_echo "$as_nl$at_banner_text$as_nl"
+  fi
+} # 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. ##
+## -------------------------------- ##
+{
+  $as_echo "## ---------------- ##
+## Tested programs. ##
+## ---------------- ##"
+  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/DMRTest.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
+
+{
+  $as_echo "## ------------------ ##
+## Running the tests. ##
+## ------------------ ##"
+} >&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 for 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_banner ORDINAL LINE DESC PAD [BANNER]
+# -------------------------------------------------
+# Declare the test group ORDINAL, located at LINE with group description DESC,
+# and residing under BANNER. Use PAD to align the status column.
+at_fn_group_banner ()
+{
+  at_setup_line="$2"
+  test -n "$5" && at_fn_banner $5
+  at_desc="$3"
+  case $1 in
+    [0-9])      at_desc_line="  $1: ";;
+    [0-9][0-9]) at_desc_line=" $1: " ;;
+    *)          at_desc_line="$1: "  ;;
+  esac
+  as_fn_append at_desc_line "$3$4"
+  $at_quiet $as_echo_n "$at_desc_line"
+  echo "#                             -*- compilation -*-" >> "$at_group_log"
+}
+
+# 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
+    yes:0)
+	at_msg="UNEXPECTED PASS"
+	at_res=xpass
+	at_errexit=$at_errexit_p
+	at_color=$at_red
+	;;
+    no:0)
+	at_msg="ok"
+	at_res=pass
+	at_errexit=false
+	at_color=$at_grn
+	;;
+    *:77)
+	at_msg='skipped ('`cat "$at_check_line_file"`')'
+	at_res=skip
+	at_errexit=false
+	at_color=$at_blu
+	;;
+    no:* | *:99)
+	at_msg='FAILED ('`cat "$at_check_line_file"`')'
+	at_res=fail
+	at_errexit=$at_errexit_p
+	at_color=$at_red
+	;;
+    yes:*)
+	at_msg='expected failure ('`cat "$at_check_line_file"`')'
+	at_res=xfail
+	at_errexit=false
+	at_color=$at_lgn
+	;;
+  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_color$at_msg$at_std"
+  else
+    # Make sure there is a separator even with long titles.
+    $as_echo " $at_color$at_msg$at_std"
+  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
+      # or the success was unexpected.
+      if $at_debug_p || test $at_res = xpass; then
+	at_fn_create_debugging_script
+	if test $at_res = xpass && $at_errexit; then
+	  echo stop > "$at_stop_file"
+	fi
+      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" | sed -n 1,${at_jobs}p`
+
+  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
+      if $at_first; then
+	exec 7>"$at_job_fifo"
+      else
+	exec 6<&-
+      fi
+      trap 'set +x; set +e
+	    trap "" PIPE
+	    echo stop > "$at_stop_file"
+	    echo >&7
+	    as_fn_exit 141' PIPE
+      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
+      echo >&7
+    ) &
+    $at_job_control_off
+    if $at_first; then
+      at_first=false
+      exec 6<"$at_job_fifo" 7>"$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
+  exec 7>&-
+  # 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
+$as_echo "## ------------- ##
+## Test results. ##
+## ------------- ##"
+echo
+{
+  echo
+  $as_echo "## ------------- ##
+## Test results. ##
+## ------------- ##"
+  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."
+  at_color=$at_red
+else
+  # Don't you just love exponential explosion of the number of cases?
+  at_color=$at_red
+  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." at_color=$at_grn ;;
+    0:0:*) at_result="$at_result behaved as expected." at_color=$at_lgn ;;
+
+    # 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_color$at_result$at_std"
+  echo "$at_result" >&5
+else
+  echo "${at_color}ERROR: $at_result$at_std" >&2
+  echo "ERROR: $at_result" >&5
+  {
+    echo
+    $as_echo "## ------------------------ ##
+## Summary of the failures. ##
+## ------------------------ ##"
+
+    # 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
+      $as_echo "## ---------------------- ##
+## Detailed failed tests. ##
+## ---------------------- ##"
+      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.14.0] $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
+at_fn_group_banner 1 'DMRTest.at:128' \
+  "parse dmr-testsuite/test_simple_1.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "1. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_1.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:128: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:128"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:128"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:128: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:128"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:128"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_1
+#AT_START_2
+at_fn_group_banner 2 'DMRTest.at:129' \
+  "parse dmr-testsuite/test_simple_2.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "2. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_2.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:129: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:129"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:129"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:129: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:129"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:129"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_2
+#AT_START_3
+at_fn_group_banner 3 'DMRTest.at:130' \
+  "parse dmr-testsuite/test_simple_3.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "3. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_3.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:130: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:130"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:130"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:130: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:130"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:130"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_3
+#AT_START_4
+at_fn_group_banner 4 'DMRTest.at:132' \
+  "parse dmr-testsuite/test_simple_3_error_1.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "4. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_3_error_1.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:132: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:132"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:132"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:132: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:132"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:132"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_4
+#AT_START_5
+at_fn_group_banner 5 'DMRTest.at:133' \
+  "parse dmr-testsuite/test_simple_3_error_2.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "5. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_3_error_2.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:133: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:133"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:133"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:133: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:133"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:133"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_5
+#AT_START_6
+at_fn_group_banner 6 'DMRTest.at:134' \
+  "parse dmr-testsuite/test_simple_3_error_3.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "6. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_3_error_3.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:134: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:134"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:134"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:134: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:134"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:134"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_6
+#AT_START_7
+at_fn_group_banner 7 'DMRTest.at:136' \
+  "parse dmr-testsuite/test_simple_4.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "7. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_4.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:136: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:136"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:136"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:136: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:136"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:136"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_7
+#AT_START_8
+at_fn_group_banner 8 'DMRTest.at:137' \
+  "parse dmr-testsuite/test_simple_5.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "8. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_5.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:137: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:137"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:137"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:137: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:137"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:137"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_8
+#AT_START_9
+at_fn_group_banner 9 'DMRTest.at:138' \
+  "parse dmr-testsuite/test_simple_6.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "9. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:138: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:138"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:138"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:138: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:138"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:138"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_9
+#AT_START_10
+at_fn_group_banner 10 'DMRTest.at:139' \
+  "parse dmr-testsuite/test_simple_7.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "10. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_7.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:139: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:139"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:139"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:139: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:139"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:139"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_10
+#AT_START_11
+at_fn_group_banner 11 'DMRTest.at:140' \
+  "parse dmr-testsuite/test_simple_8.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "11. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_8.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:140: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:140"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:140"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:140: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:140"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:140"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_11
+#AT_START_12
+at_fn_group_banner 12 'DMRTest.at:141' \
+  "parse dmr-testsuite/test_simple_9.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "12. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_9.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:141: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:141"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:141"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:141: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:141"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:141"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_12
+#AT_START_13
+at_fn_group_banner 13 'DMRTest.at:142' \
+  "parse dmr-testsuite/test_simple_9.1.xml" "        "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "13. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_9.1.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:142: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:142"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:142"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:142: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:142"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:142"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_13
+#AT_START_14
+at_fn_group_banner 14 'DMRTest.at:143' \
+  "parse dmr-testsuite/test_simple_10.xml" "         "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "14. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_10.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:143: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:143"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:143"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:143: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:143"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:143"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_14
+#AT_START_15
+at_fn_group_banner 15 'DMRTest.at:145' \
+  "parse dmr-testsuite/test_array_1.xml" "           "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "15. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:145: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:145"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:145"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:145: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:145"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:145"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_15
+#AT_START_16
+at_fn_group_banner 16 'DMRTest.at:146' \
+  "parse dmr-testsuite/test_array_2.xml" "           "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "16. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_2.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:146: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:146"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:146"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:146: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:146"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:146"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_16
+#AT_START_17
+at_fn_group_banner 17 'DMRTest.at:147' \
+  "parse dmr-testsuite/test_array_3.xml" "           "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "17. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_3.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:147: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:147"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:147"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:147: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:147"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:147"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_17
+#AT_START_18
+at_fn_group_banner 18 'DMRTest.at:148' \
+  "parse dmr-testsuite/test_array_4.xml" "           "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "18. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:148: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:148"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:148"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:148: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:148"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:148"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_18
+#AT_START_19
+at_fn_group_banner 19 'DMRTest.at:149' \
+  "parse dmr-testsuite/test_array_5.xml" "           "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "19. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_5.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:149: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:149"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:149"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:149: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:149"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:149"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_19
+#AT_START_20
+at_fn_group_banner 20 'DMRTest.at:150' \
+  "parse dmr-testsuite/test_array_6.xml" "           "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "20. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:150: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:150"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:150"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:150: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:150"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:150"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_20
+#AT_START_21
+at_fn_group_banner 21 'DMRTest.at:151' \
+  "parse dmr-testsuite/test_array_7.xml" "           "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "21. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:151: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:151"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:151"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:151: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:151"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:151"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_21
+#AT_START_22
+at_fn_group_banner 22 'DMRTest.at:152' \
+  "parse dmr-testsuite/test_array_8.xml" "           "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "22. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_8.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:152: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:152"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:152"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:152: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:152"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:152"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_22
+#AT_START_23
+at_fn_group_banner 23 'DMRTest.at:153' \
+  "parse dmr-testsuite/test_array_10.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "23. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_10.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:153: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:153"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:153"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:153: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:153"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:153"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_23
+#AT_START_24
+at_fn_group_banner 24 'DMRTest.at:154' \
+  "parse dmr-testsuite/test_array_11.xml" "          "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "24. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_11.xml
+    baseline=$input.baseline
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:154: \$abs_builddir/dmr-test -x -p \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -p $input || true" "DMRTest.at:154"
+( $at_check_trace; $abs_builddir/dmr-test -x -p $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:154"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:154: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:154"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:154"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_24
+#AT_START_25
+at_fn_group_banner 25 'DMRTest.at:158' \
+  "trans/receive dmr-testsuite/test_simple_1.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "25. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_1.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:158: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:158"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:158"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:158: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:158"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:158"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_25
+#AT_START_26
+at_fn_group_banner 26 'DMRTest.at:159' \
+  "trans/receive dmr-testsuite/test_simple_2.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "26. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_2.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:159: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:159"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:159"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:159: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:159"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:159"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_26
+#AT_START_27
+at_fn_group_banner 27 'DMRTest.at:160' \
+  "trans/receive dmr-testsuite/test_simple_3.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "27. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_3.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:160: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:160"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:160"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:160: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:160"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:160"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_27
+#AT_START_28
+at_fn_group_banner 28 'DMRTest.at:161' \
+  "trans/receive dmr-testsuite/test_simple_4.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "28. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_4.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:161: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:161"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:161"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:161: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:161"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:161"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_28
+#AT_START_29
+at_fn_group_banner 29 'DMRTest.at:162' \
+  "trans/receive dmr-testsuite/test_simple_5.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "29. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_5.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:162: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:162"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:162"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:162: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:162"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:162"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_29
+#AT_START_30
+at_fn_group_banner 30 'DMRTest.at:163' \
+  "trans/receive dmr-testsuite/test_simple_6.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "30. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:163: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:163"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:163"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:163: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:163"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:163"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_30
+#AT_START_31
+at_fn_group_banner 31 'DMRTest.at:164' \
+  "trans/receive dmr-testsuite/test_simple_7.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "31. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_7.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:164: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:164"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:164"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:164: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:164"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:164"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_31
+#AT_START_32
+at_fn_group_banner 32 'DMRTest.at:165' \
+  "trans/receive dmr-testsuite/test_simple_8.xml" "  "
+at_xfail=no
+      test "xfail" = "xfail" && at_xfail=yes
+(
+  $as_echo "32. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_8.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:165: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:165"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:165"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:165: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:165"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:165"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_32
+#AT_START_33
+at_fn_group_banner 33 'DMRTest.at:166' \
+  "trans/receive dmr-testsuite/test_simple_9.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "33. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_9.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:166: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:166"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:166"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:166: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:166"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:166"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_33
+#AT_START_34
+at_fn_group_banner 34 'DMRTest.at:167' \
+  "trans/receive dmr-testsuite/test_simple_9.1.xml" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "34. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_9.1.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:167: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:167"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:167"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:167: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:167"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:167"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_34
+#AT_START_35
+at_fn_group_banner 35 'DMRTest.at:168' \
+  "trans/receive dmr-testsuite/test_simple_10.xml" " "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "35. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_10.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:168: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:168"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:168"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:168: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:168"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:168"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_35
+#AT_START_36
+at_fn_group_banner 36 'DMRTest.at:170' \
+  "trans/receive dmr-testsuite/test_array_1.xml" "   "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "36. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:170: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:170"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:170"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:170: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:170"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:170"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_36
+#AT_START_37
+at_fn_group_banner 37 'DMRTest.at:171' \
+  "trans/receive dmr-testsuite/test_array_2.xml" "   "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "37. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_2.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:171: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:171"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:171"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:171: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:171"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:171"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_37
+#AT_START_38
+at_fn_group_banner 38 'DMRTest.at:172' \
+  "trans/receive dmr-testsuite/test_array_3.xml" "   "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "38. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_3.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:172: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:172"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:172"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:172: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:172"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:172"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_38
+#AT_START_39
+at_fn_group_banner 39 'DMRTest.at:173' \
+  "trans/receive dmr-testsuite/test_array_4.xml" "   "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "39. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:173: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:173"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:173"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:173: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:173"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:173"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_39
+#AT_START_40
+at_fn_group_banner 40 'DMRTest.at:174' \
+  "trans/receive dmr-testsuite/test_array_5.xml" "   "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "40. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_5.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:174: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:174"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:174"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:174: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:174"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:174"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_40
+#AT_START_41
+at_fn_group_banner 41 'DMRTest.at:175' \
+  "trans/receive dmr-testsuite/test_array_6.xml" "   "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "41. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:175: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:175"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:175"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:175: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:175"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:175"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_41
+#AT_START_42
+at_fn_group_banner 42 'DMRTest.at:176' \
+  "trans/receive dmr-testsuite/test_array_7.xml" "   "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "42. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:176: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:176"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:176"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:176: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:176"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:176"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_42
+#AT_START_43
+at_fn_group_banner 43 'DMRTest.at:177' \
+  "trans/receive dmr-testsuite/test_array_8.xml" "   "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "43. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_8.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:177: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:177"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:177"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:177: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:177"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:177"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_43
+#AT_START_44
+at_fn_group_banner 44 'DMRTest.at:178' \
+  "trans/receive dmr-testsuite/test_array_10.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "44. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_10.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:178: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:178"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:178"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:178: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:178"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:178"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_44
+#AT_START_45
+at_fn_group_banner 45 'DMRTest.at:179' \
+  "trans/receive dmr-testsuite/test_array_11.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "45. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_11.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:179: \$abs_builddir/dmr-test -x -t \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input || true" "DMRTest.at:179"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:179"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:179: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:179"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:179"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_45
+#AT_START_46
+at_fn_group_banner 46 'DMRTest.at:181' \
+  "intern data dmr-testsuite/test_simple_1.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "46. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_1.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:181: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:181"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:181"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:181: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:181"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:181"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_46
+#AT_START_47
+at_fn_group_banner 47 'DMRTest.at:182' \
+  "intern data dmr-testsuite/test_simple_2.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "47. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_2.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:182: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:182"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:182"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:182: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:182"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:182"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_47
+#AT_START_48
+at_fn_group_banner 48 'DMRTest.at:183' \
+  "intern data dmr-testsuite/test_simple_3.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "48. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_3.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:183: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:183"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:183"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:183: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:183"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:183"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_48
+#AT_START_49
+at_fn_group_banner 49 'DMRTest.at:184' \
+  "intern data dmr-testsuite/test_simple_4.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "49. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_4.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:184: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:184"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:184"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:184: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:184"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:184"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_49
+#AT_START_50
+at_fn_group_banner 50 'DMRTest.at:185' \
+  "intern data dmr-testsuite/test_simple_5.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "50. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_5.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:185: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:185"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:185"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:185: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:185"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:185"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_50
+#AT_START_51
+at_fn_group_banner 51 'DMRTest.at:186' \
+  "intern data dmr-testsuite/test_simple_6.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "51. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:186: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:186"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:186"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:186: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:186"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:186"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_51
+#AT_START_52
+at_fn_group_banner 52 'DMRTest.at:187' \
+  "intern data dmr-testsuite/test_simple_7.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "52. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_7.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:187: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:187"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:187"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:187: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:187"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:187"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_52
+#AT_START_53
+at_fn_group_banner 53 'DMRTest.at:188' \
+  "intern data dmr-testsuite/test_simple_8.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "53. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_8.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:188: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:188"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:188"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:188: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:188"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:188"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_53
+#AT_START_54
+at_fn_group_banner 54 'DMRTest.at:189' \
+  "intern data dmr-testsuite/test_simple_9.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "54. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_9.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:189: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:189"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:189"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:189: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:189"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:189"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_54
+#AT_START_55
+at_fn_group_banner 55 'DMRTest.at:190' \
+  "intern data dmr-testsuite/test_simple_9.1.xml" "  "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "55. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_9.1.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:190: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:190"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:190"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:190: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:190"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:190"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_55
+#AT_START_56
+at_fn_group_banner 56 'DMRTest.at:191' \
+  "intern data dmr-testsuite/test_simple_10.xml" "   "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "56. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_10.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:191: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:191"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:191"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:191: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:191"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:191"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_56
+#AT_START_57
+at_fn_group_banner 57 'DMRTest.at:193' \
+  "intern data dmr-testsuite/test_array_1.xml" "     "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "57. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:193: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:193"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:193"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:193: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:193"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:193"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_57
+#AT_START_58
+at_fn_group_banner 58 'DMRTest.at:194' \
+  "intern data dmr-testsuite/test_array_2.xml" "     "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "58. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_2.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:194: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:194"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:194"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:194: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:194"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:194"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_58
+#AT_START_59
+at_fn_group_banner 59 'DMRTest.at:195' \
+  "intern data dmr-testsuite/test_array_3.xml" "     "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "59. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_3.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:195: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:195"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:195"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:195: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:195"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:195"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_59
+#AT_START_60
+at_fn_group_banner 60 'DMRTest.at:196' \
+  "intern data dmr-testsuite/test_array_4.xml" "     "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "60. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:196: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:196"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:196"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:196: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:196"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:196"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_60
+#AT_START_61
+at_fn_group_banner 61 'DMRTest.at:197' \
+  "intern data dmr-testsuite/test_array_5.xml" "     "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "61. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_5.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:197: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:197"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:197"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:197: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:197"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:197"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_61
+#AT_START_62
+at_fn_group_banner 62 'DMRTest.at:198' \
+  "intern data dmr-testsuite/test_array_6.xml" "     "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "62. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:198: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:198"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:198"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:198: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:198"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:198"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_62
+#AT_START_63
+at_fn_group_banner 63 'DMRTest.at:199' \
+  "intern data dmr-testsuite/test_array_7.xml" "     "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "63. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:199: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:199"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:199"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:199: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:199"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:199"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_63
+#AT_START_64
+at_fn_group_banner 64 'DMRTest.at:200' \
+  "intern data dmr-testsuite/test_array_8.xml" "     "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "64. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_8.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:200: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:200"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:200"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:200: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:200"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:200"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_64
+#AT_START_65
+at_fn_group_banner 65 'DMRTest.at:201' \
+  "intern data dmr-testsuite/test_array_10.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "65. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_10.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:201: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:201"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:201"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:201: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:201"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:201"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_65
+#AT_START_66
+at_fn_group_banner 66 'DMRTest.at:202' \
+  "intern data dmr-testsuite/test_array_11.xml" "    "
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "66. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_11.xml
+    baseline=$input.trans_base
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:202: \$abs_builddir/dmr-test -x -i \$input || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -i $input || true" "DMRTest.at:202"
+( $at_check_trace; $abs_builddir/dmr-test -x -i $input || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:202"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:202: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:202"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:202"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_66
+#AT_START_67
+at_fn_group_banner 67 'DMRTest.at:206' \
+  "trans/receive dmr-testsuite/test_array_4.xml a" " "
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "67. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_4.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:206: \$abs_builddir/dmr-test -x -t \$input -c \"a\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a\" || true" "DMRTest.at:206"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:206"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:206: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:206"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:206"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_67
+#AT_START_68
+at_fn_group_banner 68 'DMRTest.at:207' \
+  "trans/receive dmr-testsuite/test_array_4.xml a[][] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "68. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_4.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:207: \$abs_builddir/dmr-test -x -t \$input -c \"a[][] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a[][] \" || true" "DMRTest.at:207"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a[][] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:207"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:207: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:207"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:207"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_68
+#AT_START_69
+at_fn_group_banner 69 'DMRTest.at:209' \
+  "trans/receive dmr-testsuite/test_array_4.xml /row=[0:1];/col=[3];a" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "69. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_4.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:209: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[0:1];/col=[3];a\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[0:1];/col=[3];a\" || true" "DMRTest.at:209"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[0:1];/col=[3];a" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:209"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:209: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:209"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:209"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_69
+#AT_START_70
+at_fn_group_banner 70 'DMRTest.at:211' \
+  "trans/receive dmr-testsuite/test_array_4.xml /row=[0:1];/col=[3];a[][] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "70. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_4.xml.4.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:211: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[0:1];/col=[3];a[][] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[0:1];/col=[3];a[][] \" || true" "DMRTest.at:211"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[0:1];/col=[3];a[][] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:211"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:211: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:211"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:211"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_70
+#AT_START_71
+at_fn_group_banner 71 'DMRTest.at:213' \
+  "trans/receive dmr-testsuite/test_array_4.xml /row=[0:1];/col=[3];a[][];b[0][];c[0:][0:] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "71. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_4.xml.5.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:213: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[0:1];/col=[3];a[][];b[0][];c[0:][0:] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[0:1];/col=[3];a[][];b[0][];c[0:][0:] \" || true" "DMRTest.at:213"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[0:1];/col=[3];a[][];b[0][];c[0:][0:] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:213"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:213: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:213"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:213"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_71
+#AT_START_72
+at_fn_group_banner 72 'DMRTest.at:215' \
+  "trans/receive dmr-testsuite/test_array_4.xml x[][] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "72. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_4.xml.6.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:215: \$abs_builddir/dmr-test -x -t \$input -c \"x[][] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"x[][] \" || true" "DMRTest.at:215"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "x[][] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:215"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:215: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:215"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:215"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_72
+#AT_START_73
+at_fn_group_banner 73 'DMRTest.at:216' \
+  "trans/receive dmr-testsuite/test_array_4.xml /row=[0:1];x[][] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "73. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_4.xml.7.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:216: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[0:1];x[][] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[0:1];x[][] \" || true" "DMRTest.at:216"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[0:1];x[][] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:216"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:216: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:216"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:216"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_73
+#AT_START_74
+at_fn_group_banner 74 'DMRTest.at:218' \
+  "trans/receive dmr-testsuite/test_array_4.xml c[2:][2:] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "74. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_4.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_4.xml.8.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:218: \$abs_builddir/dmr-test -x -t \$input -c \"c[2:][2:] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"c[2:][2:] \" || true" "DMRTest.at:218"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "c[2:][2:] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:218"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:218: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:218"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:218"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_74
+#AT_START_75
+at_fn_group_banner 75 'DMRTest.at:220' \
+  "trans/receive dmr-testsuite/test_simple_6.xml s" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "75. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_6.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:220: \$abs_builddir/dmr-test -x -t \$input -c \"s\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s\" || true" "DMRTest.at:220"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:220"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:220: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:220"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:220"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_75
+#AT_START_76
+at_fn_group_banner 76 'DMRTest.at:221' \
+  "trans/receive dmr-testsuite/test_simple_6.xml s.i1" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "76. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_6.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:221: \$abs_builddir/dmr-test -x -t \$input -c \"s.i1\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s.i1\" || true" "DMRTest.at:221"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s.i1" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:221"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:221: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:221"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:221"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_76
+#AT_START_77
+at_fn_group_banner 77 'DMRTest.at:222' \
+  "trans/receive dmr-testsuite/test_simple_6.xml s.s" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "77. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_6.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:222: \$abs_builddir/dmr-test -x -t \$input -c \"s.s\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s.s\" || true" "DMRTest.at:222"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s.s" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:222"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:222: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:222"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:222"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_77
+#AT_START_78
+at_fn_group_banner 78 'DMRTest.at:223' \
+  "trans/receive dmr-testsuite/test_simple_6.1.xml s.inner.i2" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "78. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_6.1.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:223: \$abs_builddir/dmr-test -x -t \$input -c \"s.inner.i2\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s.inner.i2\" || true" "DMRTest.at:223"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s.inner.i2" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:223"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:223: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:223"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:223"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_78
+#AT_START_79
+at_fn_group_banner 79 'DMRTest.at:225' \
+  "trans/receive dmr-testsuite/test_simple_6.xml s{i1}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "79. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_6.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:225: \$abs_builddir/dmr-test -x -t \$input -c \"s{i1}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{i1}\" || true" "DMRTest.at:225"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{i1}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:225"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:225: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:225"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:225"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_79
+#AT_START_80
+at_fn_group_banner 80 'DMRTest.at:226' \
+  "trans/receive dmr-testsuite/test_simple_6.xml s{s}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "80. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_6.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:226: \$abs_builddir/dmr-test -x -t \$input -c \"s{s}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{s}\" || true" "DMRTest.at:226"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{s}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:226"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:226: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:226"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:226"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_80
+#AT_START_81
+at_fn_group_banner 81 'DMRTest.at:227' \
+  "trans/receive dmr-testsuite/test_simple_6.1.xml s{inner.i2}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "81. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_6.1.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:227: \$abs_builddir/dmr-test -x -t \$input -c \"s{inner.i2}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{inner.i2}\" || true" "DMRTest.at:227"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{inner.i2}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:227"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:227: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:227"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:227"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_81
+#AT_START_82
+at_fn_group_banner 82 'DMRTest.at:228' \
+  "trans/receive dmr-testsuite/test_simple_6.1.xml s{inner{i2}}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "82. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_6.1.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:228: \$abs_builddir/dmr-test -x -t \$input -c \"s{inner{i2}}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{inner{i2}}\" || true" "DMRTest.at:228"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{inner{i2}}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:228"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:228: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:228"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:228"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_82
+#AT_START_83
+at_fn_group_banner 83 'DMRTest.at:231' \
+  "trans/receive dmr-testsuite/test_array_6.xml a" " "
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "83. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:231: \$abs_builddir/dmr-test -x -t \$input -c \"a\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a\" || true" "DMRTest.at:231"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:231"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:231: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:231"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:231"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_83
+#AT_START_84
+at_fn_group_banner 84 'DMRTest.at:232' \
+  "trans/receive dmr-testsuite/test_array_6.xml a[][] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "84. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:232: \$abs_builddir/dmr-test -x -t \$input -c \"a[][] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a[][] \" || true" "DMRTest.at:232"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a[][] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:232"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:232: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:232"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:232"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_84
+#AT_START_85
+at_fn_group_banner 85 'DMRTest.at:233' \
+  "trans/receive dmr-testsuite/test_array_6.xml /row=[0:1];a[][] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "85. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:233: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[0:1];a[][] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[0:1];a[][] \" || true" "DMRTest.at:233"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[0:1];a[][] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:233"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:233: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:233"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:233"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_85
+#AT_START_86
+at_fn_group_banner 86 'DMRTest.at:234' \
+  "trans/receive dmr-testsuite/test_array_6.xml /row=[0:1];a[][1:2] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "86. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:234: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[0:1];a[][1:2] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[0:1];a[][1:2] \" || true" "DMRTest.at:234"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[0:1];a[][1:2] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:234"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:234: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:234"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:234"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_86
+#AT_START_87
+at_fn_group_banner 87 'DMRTest.at:237' \
+  "trans/receive dmr-testsuite/test_array_6.2.xml a" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "87. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.2.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:237: \$abs_builddir/dmr-test -x -t \$input -c \"a\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a\" || true" "DMRTest.at:237"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:237"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:237: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:237"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:237"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_87
+#AT_START_88
+at_fn_group_banner 88 'DMRTest.at:238' \
+  "trans/receive dmr-testsuite/test_array_6.2.xml a{i;j}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "88. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.2.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:238: \$abs_builddir/dmr-test -x -t \$input -c \"a{i;j}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a{i;j}\" || true" "DMRTest.at:238"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a{i;j}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:238"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:238: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:238"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:238"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_88
+#AT_START_89
+at_fn_group_banner 89 'DMRTest.at:239' \
+  "trans/receive dmr-testsuite/test_array_6.2.xml a.i" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "89. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.2.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:239: \$abs_builddir/dmr-test -x -t \$input -c \"a.i\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a.i\" || true" "DMRTest.at:239"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a.i" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:239"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:239: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:239"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:239"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_89
+#AT_START_90
+at_fn_group_banner 90 'DMRTest.at:240' \
+  "trans/receive dmr-testsuite/test_array_6.2.xml a{i}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "90. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.2.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:240: \$abs_builddir/dmr-test -x -t \$input -c \"a{i}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a{i}\" || true" "DMRTest.at:240"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a{i}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:240"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:240: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:240"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:240"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_90
+#AT_START_91
+at_fn_group_banner 91 'DMRTest.at:241' \
+  "trans/receive dmr-testsuite/test_array_6.2.xml a.i[0][1:2] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "91. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.2.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:241: \$abs_builddir/dmr-test -x -t \$input -c \"a.i[0][1:2] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a.i[0][1:2] \" || true" "DMRTest.at:241"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a.i[0][1:2] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:241"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:241: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:241"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:241"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_91
+#AT_START_92
+at_fn_group_banner 92 'DMRTest.at:242' \
+  "trans/receive dmr-testsuite/test_array_6.2.xml a{i[0][1:2]} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "92. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.2.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:242: \$abs_builddir/dmr-test -x -t \$input -c \"a{i[0][1:2]} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a{i[0][1:2]} \" || true" "DMRTest.at:242"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a{i[0][1:2]} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:242"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:242: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:242"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:242"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_92
+#AT_START_93
+at_fn_group_banner 93 'DMRTest.at:243' \
+  "trans/receive dmr-testsuite/test_array_6.2.xml /row=[0:1];a.i[][1:2] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "93. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.2.xml.4.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:243: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[0:1];a.i[][1:2] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[0:1];a.i[][1:2] \" || true" "DMRTest.at:243"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[0:1];a.i[][1:2] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:243"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:243: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:243"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:243"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_93
+#AT_START_94
+at_fn_group_banner 94 'DMRTest.at:244' \
+  "trans/receive dmr-testsuite/test_array_6.2.xml /row=[0:1];a{i[][1:2]} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "94. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.2.xml.4.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:244: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[0:1];a{i[][1:2]} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[0:1];a{i[][1:2]} \" || true" "DMRTest.at:244"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[0:1];a{i[][1:2]} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:244"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:244: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:244"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:244"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_94
+#AT_START_95
+at_fn_group_banner 95 'DMRTest.at:246' \
+  "trans/receive dmr-testsuite/test_array_6.2.xml a.j" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "95. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.2.xml.5.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:246: \$abs_builddir/dmr-test -x -t \$input -c \"a.j\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a.j\" || true" "DMRTest.at:246"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a.j" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:246"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:246: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:246"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:246"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_95
+#AT_START_96
+at_fn_group_banner 96 'DMRTest.at:249' \
+  "trans/receive dmr-testsuite/test_array_6.1.xml a" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "96. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.1.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:249: \$abs_builddir/dmr-test -x -t \$input -c \"a\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a\" || true" "DMRTest.at:249"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:249"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:249: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:249"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:249"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_96
+#AT_START_97
+at_fn_group_banner 97 'DMRTest.at:252' \
+  "trans/receive dmr-testsuite/test_array_6.1.xml /row=[1:2];a[][0] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "97. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.1.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:252: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[1:2];a[][0] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[1:2];a[][0] \" || true" "DMRTest.at:252"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[1:2];a[][0] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:252"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:252: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:252"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:252"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_97
+#AT_START_98
+at_fn_group_banner 98 'DMRTest.at:253' \
+  "trans/receive dmr-testsuite/test_array_6.1.xml /row=[1:2];a[][0]{i;j} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "98. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.1.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:253: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[1:2];a[][0]{i;j} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[1:2];a[][0]{i;j} \" || true" "DMRTest.at:253"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[1:2];a[][0]{i;j} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:253"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:253: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:253"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:253"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_98
+#AT_START_99
+at_fn_group_banner 99 'DMRTest.at:255' \
+  "trans/receive dmr-testsuite/test_array_6.1.xml row=[1:2];a[][0]{i;j} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "99. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.1.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:255: \$abs_builddir/dmr-test -x -t \$input -c \"row=[1:2];a[][0]{i;j} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"row=[1:2];a[][0]{i;j} \" || true" "DMRTest.at:255"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "row=[1:2];a[][0]{i;j} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:255"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:255: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:255"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:255"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_99
+#AT_START_100
+at_fn_group_banner 100 'DMRTest.at:258' \
+  "trans/receive dmr-testsuite/test_array_6.1.xml a{i[1:2][1:3];j} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "100. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.1.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:258: \$abs_builddir/dmr-test -x -t \$input -c \"a{i[1:2][1:3];j} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a{i[1:2][1:3];j} \" || true" "DMRTest.at:258"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a{i[1:2][1:3];j} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:258"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:258: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:258"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:258"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_100
+#AT_START_101
+at_fn_group_banner 101 'DMRTest.at:259' \
+  "trans/receive dmr-testsuite/test_array_6.1.xml a[][]{i[1:2][1:3];j} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "101. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.1.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:259: \$abs_builddir/dmr-test -x -t \$input -c \"a[][]{i[1:2][1:3];j} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"a[][]{i[1:2][1:3];j} \" || true" "DMRTest.at:259"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "a[][]{i[1:2][1:3];j} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:259"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:259: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:259"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:259"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_101
+#AT_START_102
+at_fn_group_banner 102 'DMRTest.at:263' \
+  "trans/receive dmr-testsuite/test_array_6.1.xml /row=[1];a[][0]{i[][0:1]} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "102. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_6.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_6.1.xml.4.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:263: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[1];a[][0]{i[][0:1]} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[1];a[][0]{i[][0:1]} \" || true" "DMRTest.at:263"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[1];a[][0]{i[][0:1]} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:263"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:263: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:263"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:263"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_102
+#AT_START_103
+at_fn_group_banner 103 'DMRTest.at:266' \
+  "trans/receive dmr-testsuite/test_simple_7.xml s" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "103. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_7.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:266: \$abs_builddir/dmr-test -x -t \$input -c \"s\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s\" || true" "DMRTest.at:266"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:266"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:266: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:266"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:266"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_103
+#AT_START_104
+at_fn_group_banner 104 'DMRTest.at:267' \
+  "trans/receive dmr-testsuite/test_simple_7.xml s{i1;s}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "104. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_7.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:267: \$abs_builddir/dmr-test -x -t \$input -c \"s{i1;s}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{i1;s}\" || true" "DMRTest.at:267"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{i1;s}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:267"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:267: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:267"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:267"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_104
+#AT_START_105
+at_fn_group_banner 105 'DMRTest.at:269' \
+  "trans/receive dmr-testsuite/test_simple_7.xml s.i1" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "105. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_7.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:269: \$abs_builddir/dmr-test -x -t \$input -c \"s.i1\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s.i1\" || true" "DMRTest.at:269"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s.i1" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:269"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:269: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:269"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:269"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_105
+#AT_START_106
+at_fn_group_banner 106 'DMRTest.at:270' \
+  "trans/receive dmr-testsuite/test_simple_7.xml s{i1}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "106. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_7.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:270: \$abs_builddir/dmr-test -x -t \$input -c \"s{i1}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{i1}\" || true" "DMRTest.at:270"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{i1}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:270"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:270: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:270"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:270"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_106
+#AT_START_107
+at_fn_group_banner 107 'DMRTest.at:272' \
+  "trans/receive dmr-testsuite/test_simple_8.xml outer" ""
+at_xfail=no
+      test "Xxfail" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "107. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_8.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_8.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:272: \$abs_builddir/dmr-test -x -t \$input -c \"outer\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"outer\" || true" "DMRTest.at:272"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "outer" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:272"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:272: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:272"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:272"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_107
+#AT_START_108
+at_fn_group_banner 108 'DMRTest.at:273' \
+  "trans/receive dmr-testsuite/test_simple_8.xml outer.s.s" ""
+at_xfail=no
+      test "Xxfail" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "108. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_8.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_8.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:273: \$abs_builddir/dmr-test -x -t \$input -c \"outer.s.s\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"outer.s.s\" || true" "DMRTest.at:273"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "outer.s.s" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:273"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:273: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:273"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:273"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_108
+#AT_START_109
+at_fn_group_banner 109 'DMRTest.at:274' \
+  "trans/receive dmr-testsuite/test_simple_8.xml outer{s{s}}" ""
+at_xfail=no
+      test "Xxfail" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "109. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_simple_8.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_simple_8.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:274: \$abs_builddir/dmr-test -x -t \$input -c \"outer{s{s}}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"outer{s{s}}\" || true" "DMRTest.at:274"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "outer{s{s}}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:274"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:274: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:274"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:274"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_109
+#AT_START_110
+at_fn_group_banner 110 'DMRTest.at:276' \
+  "trans/receive dmr-testsuite/test_array_7.xml s" " "
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "110. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:276: \$abs_builddir/dmr-test -x -t \$input -c \"s\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s\" || true" "DMRTest.at:276"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:276"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:276: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:276"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:276"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_110
+#AT_START_111
+at_fn_group_banner 111 'DMRTest.at:277' \
+  "trans/receive dmr-testsuite/test_array_7.xml s{i1;s}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "111. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:277: \$abs_builddir/dmr-test -x -t \$input -c \"s{i1;s}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{i1;s}\" || true" "DMRTest.at:277"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{i1;s}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:277"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:277: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:277"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:277"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_111
+#AT_START_112
+at_fn_group_banner 112 'DMRTest.at:279' \
+  "trans/receive dmr-testsuite/test_array_7.xml s.i1" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "112. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:279: \$abs_builddir/dmr-test -x -t \$input -c \"s.i1\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s.i1\" || true" "DMRTest.at:279"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s.i1" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:279"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:279: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:279"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:279"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_112
+#AT_START_113
+at_fn_group_banner 113 'DMRTest.at:280' \
+  "trans/receive dmr-testsuite/test_array_7.xml s{i1}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "113. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:280: \$abs_builddir/dmr-test -x -t \$input -c \"s{i1}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{i1}\" || true" "DMRTest.at:280"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{i1}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:280"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:280: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:280"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:280"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_113
+#AT_START_114
+at_fn_group_banner 114 'DMRTest.at:282' \
+  "trans/receive dmr-testsuite/test_array_7.xml s[1] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "114. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:282: \$abs_builddir/dmr-test -x -t \$input -c \"s[1] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s[1] \" || true" "DMRTest.at:282"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s[1] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:282"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:282: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:282"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:282"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_114
+#AT_START_115
+at_fn_group_banner 115 'DMRTest.at:283' \
+  "trans/receive dmr-testsuite/test_array_7.xml s[1]{i1;s}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "115. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:283: \$abs_builddir/dmr-test -x -t \$input -c \"s[1]{i1;s}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s[1]{i1;s}\" || true" "DMRTest.at:283"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s[1]{i1;s}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:283"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:283: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:283"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:283"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_115
+#AT_START_116
+at_fn_group_banner 116 'DMRTest.at:285' \
+  "trans/receive dmr-testsuite/test_array_7.xml s[1]{i1}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "116. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.xml.4.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:285: \$abs_builddir/dmr-test -x -t \$input -c \"s[1]{i1}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s[1]{i1}\" || true" "DMRTest.at:285"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s[1]{i1}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:285"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:285: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:285"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:285"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_116
+#AT_START_117
+at_fn_group_banner 117 'DMRTest.at:288' \
+  "trans/receive dmr-testsuite/test_array_8.xml /col=[1:2];s[1][]{i1}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "117. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_8.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_8.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:288: \$abs_builddir/dmr-test -x -t \$input -c \"/col=[1:2];s[1][]{i1}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/col=[1:2];s[1][]{i1}\" || true" "DMRTest.at:288"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/col=[1:2];s[1][]{i1}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:288"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:288: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:288"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:288"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_117
+#AT_START_118
+at_fn_group_banner 118 'DMRTest.at:289' \
+  "trans/receive dmr-testsuite/test_array_8.xml col=[1:2];s[1][]{i1}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "118. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_8.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_8.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:289: \$abs_builddir/dmr-test -x -t \$input -c \"col=[1:2];s[1][]{i1}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"col=[1:2];s[1][]{i1}\" || true" "DMRTest.at:289"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "col=[1:2];s[1][]{i1}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:289"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:289: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:289"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:289"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_118
+#AT_START_119
+at_fn_group_banner 119 'DMRTest.at:292' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "119. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:292: \$abs_builddir/dmr-test -x -t \$input -c \"\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"\" || true" "DMRTest.at:292"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:292"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:292: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:292"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:292"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_119
+#AT_START_120
+at_fn_group_banner 120 'DMRTest.at:293' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml s" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "120. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:293: \$abs_builddir/dmr-test -x -t \$input -c \"s\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s\" || true" "DMRTest.at:293"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:293"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:293: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:293"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:293"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_120
+#AT_START_121
+at_fn_group_banner 121 'DMRTest.at:295' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml s.i1" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "121. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:295: \$abs_builddir/dmr-test -x -t \$input -c \"s.i1\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s.i1\" || true" "DMRTest.at:295"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s.i1" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:295"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:295: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:295"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:295"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_121
+#AT_START_122
+at_fn_group_banner 122 'DMRTest.at:296' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml s.i1[][] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "122. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:296: \$abs_builddir/dmr-test -x -t \$input -c \"s.i1[][] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s.i1[][] \" || true" "DMRTest.at:296"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s.i1[][] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:296"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:296: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:296"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:296"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_122
+#AT_START_123
+at_fn_group_banner 123 'DMRTest.at:297' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml s{i1}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "123. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:297: \$abs_builddir/dmr-test -x -t \$input -c \"s{i1}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{i1}\" || true" "DMRTest.at:297"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{i1}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:297"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:297: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:297"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:297"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_123
+#AT_START_124
+at_fn_group_banner 124 'DMRTest.at:298' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml s{i1[][]} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "124. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:298: \$abs_builddir/dmr-test -x -t \$input -c \"s{i1[][]} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{i1[][]} \" || true" "DMRTest.at:298"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{i1[][]} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:298"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:298: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:298"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:298"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_124
+#AT_START_125
+at_fn_group_banner 125 'DMRTest.at:300' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml s.i1[0][0] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "125. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:300: \$abs_builddir/dmr-test -x -t \$input -c \"s.i1[0][0] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s.i1[0][0] \" || true" "DMRTest.at:300"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s.i1[0][0] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:300"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:300: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:300"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:300"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_125
+#AT_START_126
+at_fn_group_banner 126 'DMRTest.at:301' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml s{i1[0][0]} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "126. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:301: \$abs_builddir/dmr-test -x -t \$input -c \"s{i1[0][0]} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s{i1[0][0]} \" || true" "DMRTest.at:301"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s{i1[0][0]} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:301"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:301: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:301"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:301"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_126
+#AT_START_127
+at_fn_group_banner 127 'DMRTest.at:303' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml s.i1[0:2][1:2] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "127. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.4.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:303: \$abs_builddir/dmr-test -x -t \$input -c \"s.i1[0:2][1:2] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"s.i1[0:2][1:2] \" || true" "DMRTest.at:303"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "s.i1[0:2][1:2] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:303"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:303: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:303"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:303"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_127
+#AT_START_128
+at_fn_group_banner 128 'DMRTest.at:307' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "128. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.5.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:307: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[2:3];/col=[2:3];s \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[2:3];/col=[2:3];s \" || true" "DMRTest.at:307"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[2:3];/col=[2:3];s " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:307"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:307: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:307"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:307"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_128
+#AT_START_129
+at_fn_group_banner 129 'DMRTest.at:309' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s.i1 " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "129. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.6.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:309: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[2:3];/col=[2:3];s.i1 \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[2:3];/col=[2:3];s.i1 \" || true" "DMRTest.at:309"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[2:3];/col=[2:3];s.i1 " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:309"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:309: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:309"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:309"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_129
+#AT_START_130
+at_fn_group_banner 130 'DMRTest.at:310' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s.i1[][] " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "130. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.6.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:310: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[2:3];/col=[2:3];s.i1[][] \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[2:3];/col=[2:3];s.i1[][] \" || true" "DMRTest.at:310"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[2:3];/col=[2:3];s.i1[][] " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:310"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:310: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:310"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:310"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_130
+#AT_START_131
+at_fn_group_banner 131 'DMRTest.at:311' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s{i1} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "131. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.6.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:311: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[2:3];/col=[2:3];s{i1} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[2:3];/col=[2:3];s{i1} \" || true" "DMRTest.at:311"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[2:3];/col=[2:3];s{i1} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:311"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:311: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:311"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:311"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_131
+#AT_START_132
+at_fn_group_banner 132 'DMRTest.at:312' \
+  "trans/receive dmr-testsuite/test_array_7.1.xml /row=[2:3];/col=[2:3];s{i1[][]} " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "132. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.1.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.1.xml.6.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:312: \$abs_builddir/dmr-test -x -t \$input -c \"/row=[2:3];/col=[2:3];s{i1[][]} \" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/row=[2:3];/col=[2:3];s{i1[][]} \" || true" "DMRTest.at:312"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/row=[2:3];/col=[2:3];s{i1[][]} " || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:312"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:312: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:312"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:312"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_132
+#AT_START_133
+at_fn_group_banner 133 'DMRTest.at:315' \
+  "trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[]{i1}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "133. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.2.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:315: \$abs_builddir/dmr-test -x -t \$input -c \"/col=[1:2];s[]{i1}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/col=[1:2];s[]{i1}\" || true" "DMRTest.at:315"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/col=[1:2];s[]{i1}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:315"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:315: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:315"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:315"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_133
+#AT_START_134
+at_fn_group_banner 134 'DMRTest.at:316' \
+  "trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[]{i1[][]}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "134. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.2.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:316: \$abs_builddir/dmr-test -x -t \$input -c \"/col=[1:2];s[]{i1[][]}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/col=[1:2];s[]{i1[][]}\" || true" "DMRTest.at:316"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/col=[1:2];s[]{i1[][]}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:316"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:316: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:316"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:316"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_134
+#AT_START_135
+at_fn_group_banner 135 'DMRTest.at:317' \
+  "trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s{i1[][]}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "135. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.2.xml.1.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:317: \$abs_builddir/dmr-test -x -t \$input -c \"/col=[1:2];s{i1[][]}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/col=[1:2];s{i1[][]}\" || true" "DMRTest.at:317"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/col=[1:2];s{i1[][]}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:317"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:317: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:317"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:317"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_135
+#AT_START_136
+at_fn_group_banner 136 'DMRTest.at:319' \
+  "trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[]{i1[0][]}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "136. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.2.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:319: \$abs_builddir/dmr-test -x -t \$input -c \"/col=[1:2];s[]{i1[0][]}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/col=[1:2];s[]{i1[0][]}\" || true" "DMRTest.at:319"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/col=[1:2];s[]{i1[0][]}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:319"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:319: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:319"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:319"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_136
+#AT_START_137
+at_fn_group_banner 137 'DMRTest.at:320' \
+  "trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s{i1[0][]}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "137. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.2.xml.2.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:320: \$abs_builddir/dmr-test -x -t \$input -c \"/col=[1:2];s{i1[0][]}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/col=[1:2];s{i1[0][]}\" || true" "DMRTest.at:320"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/col=[1:2];s{i1[0][]}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:320"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:320: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:320"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:320"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_137
+#AT_START_138
+at_fn_group_banner 138 'DMRTest.at:322' \
+  "trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[0]{i1}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "138. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.2.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:322: \$abs_builddir/dmr-test -x -t \$input -c \"/col=[1:2];s[0]{i1}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/col=[1:2];s[0]{i1}\" || true" "DMRTest.at:322"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/col=[1:2];s[0]{i1}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:322"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:322: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:322"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:322"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_138
+#AT_START_139
+at_fn_group_banner 139 'DMRTest.at:323' \
+  "trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[0]{i1[][]}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "139. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.2.xml.3.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:323: \$abs_builddir/dmr-test -x -t \$input -c \"/col=[1:2];s[0]{i1[][]}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/col=[1:2];s[0]{i1[][]}\" || true" "DMRTest.at:323"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/col=[1:2];s[0]{i1[][]}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:323"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:323: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:323"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:323"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_139
+#AT_START_140
+at_fn_group_banner 140 'DMRTest.at:325' \
+  "trans/receive dmr-testsuite/test_array_7.2.xml /col=[1:2];s[0]{i1[0][]}" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "140. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_7.2.xml
+    baseline=$abs_srcdir/dmr-testsuite/test_array_7.2.xml.4.trans_base
+
+    # echo "baseline: $baseline"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:325: \$abs_builddir/dmr-test -x -t \$input -c \"/col=[1:2];s[0]{i1[0][]}\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -c \"/col=[1:2];s[0]{i1[0][]}\" || true" "DMRTest.at:325"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -c "/col=[1:2];s[0]{i1[0][]}" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:325"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:325: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:325"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:325"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_140
+#AT_START_141
+at_fn_group_banner 141 'DMRTest.at:329' \
+  "trans/receive dmr-testsuite/test_array_1.xml scale(x,1) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "141. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    fe="scale(x,1)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_1.xml.1.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:329: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:329"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:329"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:329: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:329"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:329"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_141
+#AT_START_142
+at_fn_group_banner 142 'DMRTest.at:330' \
+  "trans/receive dmr-testsuite/test_array_1.xml scale(x,10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "142. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    fe="scale(x,10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_1.xml.2.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:330: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:330"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:330"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:330: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:330"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:330"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_142
+#AT_START_143
+at_fn_group_banner 143 'DMRTest.at:331' \
+  "trans/receive dmr-testsuite/test_array_1.xml scale(x,-10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "143. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    fe="scale(x,-10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_1.xml.3.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:331: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:331"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:331"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:331: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:331"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:331"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_143
+#AT_START_144
+at_fn_group_banner 144 'DMRTest.at:332' \
+  "trans/receive dmr-testsuite/test_array_1.xml scale(x,0.001) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "144. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    fe="scale(x,0.001)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_1.xml.4.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:332: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:332"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:332"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:332: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:332"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:332"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_144
+#AT_START_145
+at_fn_group_banner 145 'DMRTest.at:333' \
+  "trans/receive dmr-testsuite/test_array_1.xml scale(x,-0.001) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "145. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    fe="scale(x,-0.001)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_1.xml.5.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:333: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:333"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:333"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:333: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:333"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:333"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_145
+#AT_START_146
+at_fn_group_banner 146 'DMRTest.at:337' \
+  "trans/receive dmr-testsuite/test_array_1.xml scale(x,0x7fffffffffffffff) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "146. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    fe="scale(x,0x7fffffffffffffff)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_1.xml.6.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:337: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:337"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:337"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:337: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:337"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:337"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_146
+#AT_START_147
+at_fn_group_banner 147 'DMRTest.at:339' \
+  "trans/receive dmr-testsuite/test_array_1.xml scale(x,0x8fffffffffffffff) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "147. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_1.xml
+    fe="scale(x,0x8fffffffffffffff)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_1.xml.7.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:339: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:339"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:339"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:339: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:339"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:339"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_147
+#AT_START_148
+at_fn_group_banner 148 'DMRTest.at:343' \
+  "trans/receive dmr-testsuite/test_array_5.xml scale(a,0.001) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "148. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_5.xml
+    fe="scale(a,0.001)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_5.xml.1.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:343: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:343"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:343"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:343: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:343"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:343"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_148
+#AT_START_149
+at_fn_group_banner 149 'DMRTest.at:344' \
+  "trans/receive dmr-testsuite/test_array_5.xml scale(b,0.001) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "149. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_5.xml
+    fe="scale(b,0.001)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_5.xml.2.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:344: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:344"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:344"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:344: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:344"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:344"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_149
+#AT_START_150
+at_fn_group_banner 150 'DMRTest.at:346' \
+  "trans/receive dmr-testsuite/test_array_5.xml scale(c,0.001) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "150. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_5.xml
+    fe="scale(c,0.001)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_5.xml.3.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:346: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:346"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:346"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:346: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:346"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:346"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_150
+#AT_START_151
+at_fn_group_banner 151 'DMRTest.at:347' \
+  "trans/receive dmr-testsuite/test_array_5.xml scale(d,0.001) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "151. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/test_array_5.xml
+    fe="scale(d,0.001)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/test_array_5.xml.4.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:347: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:347"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:347"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:347: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:347"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:347"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_151
+#AT_START_152
+at_fn_group_banner 152 'DMRTest.at:352' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(u,10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "152. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(u,10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.1.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:352: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:352"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:352"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:352: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:352"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:352"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_152
+#AT_START_153
+at_fn_group_banner 153 'DMRTest.at:353' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(u,v) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "153. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(u,v)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.2.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:353: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:353"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:353"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:353: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:353"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:353"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_153
+#AT_START_154
+at_fn_group_banner 154 'DMRTest.at:354' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(scale(u,10),0.01) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "154. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(scale(u,10),0.01)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.3.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:354: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:354"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:354"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:354: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:354"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:354"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_154
+#AT_START_155
+at_fn_group_banner 155 'DMRTest.at:357' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(Point.x,10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "155. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(Point.x,10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.4.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:357: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:357"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:357"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:357: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:357"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:357"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_155
+#AT_START_156
+at_fn_group_banner 156 'DMRTest.at:358' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(Point.x,Point.y) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "156. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(Point.x,Point.y)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.5.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:358: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:358"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:358"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:358: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:358"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:358"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_156
+#AT_START_157
+at_fn_group_banner 157 'DMRTest.at:359' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(scale(Point.x,10),0.01) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "157. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(scale(Point.x,10),0.01)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.6.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:359: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:359"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:359"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:359: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:359"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:359"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_157
+#AT_START_158
+at_fn_group_banner 158 'DMRTest.at:362' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Byte(20:1,2,3,4),10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "158. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$Byte(20:1,2,3,4),10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.7.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:362: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:362"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:362"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:362: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:362"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:362"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_158
+#AT_START_159
+at_fn_group_banner 159 'DMRTest.at:363' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Int8(20:10,11,12,-9),10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "159. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$Int8(20:10,11,12,-9),10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.8.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:363: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:363"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:363"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:363: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:363"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:363"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_159
+#AT_START_160
+at_fn_group_banner 160 'DMRTest.at:364' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$UInt16(20:1,2,3,4),10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "160. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$UInt16(20:1,2,3,4),10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.9.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:364: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:364"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:364"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:364: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:364"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:364"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_160
+#AT_START_161
+at_fn_group_banner 161 'DMRTest.at:365' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Int16(20:1,2,3,-4),10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "161. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$Int16(20:1,2,3,-4),10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.10.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:365: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:365"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:365"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:365: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:365"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:365"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_161
+#AT_START_162
+at_fn_group_banner 162 'DMRTest.at:366' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$UInt32(20:1,2,3,4),10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "162. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$UInt32(20:1,2,3,4),10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.11.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:366: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:366"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:366"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:366: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:366"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:366"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_162
+#AT_START_163
+at_fn_group_banner 163 'DMRTest.at:367' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Int32(20:1,2,3,-4),10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "163. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$Int32(20:1,2,3,-4),10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.12.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:367: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:367"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:367"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:367: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:367"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:367"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_163
+#AT_START_164
+at_fn_group_banner 164 'DMRTest.at:368' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$UInt64(20:1,2,3,0xffffffffffffffff),1) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "164. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$UInt64(20:1,2,3,0xffffffffffffffff),1)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.13.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:368: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:368"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:368"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:368: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:368"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:368"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_164
+#AT_START_165
+at_fn_group_banner 165 'DMRTest.at:369' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Int64(20:1,2,3,0x7fffffffffffffff),1) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "165. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$Int64(20:1,2,3,0x7fffffffffffffff),1)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.14.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:369: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:369"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:369"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:369: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:369"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:369"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_165
+#AT_START_166
+at_fn_group_banner 166 'DMRTest.at:370' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Float32(20:1,2,3,4.55),10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "166. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$Float32(20:1,2,3,4.55),10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.15.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:370: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:370"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:370"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:370: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:370"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:370"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_166
+#AT_START_167
+at_fn_group_banner 167 'DMRTest.at:371' \
+  "trans/receive dmr-testsuite/vol_1_ce_1.xml scale(\\\$Float64(20:1,2,3,4.55),10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "167. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml
+    fe="scale(\$Float64(20:1,2,3,4.55),10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_1.xml.16.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:371: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:371"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:371"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:371: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:371"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:371"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_167
+#AT_START_168
+at_fn_group_banner 168 'DMRTest.at:375' \
+  "trans/receive dmr-testsuite/vol_1_ce_10.xml scale(lat,10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "168. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_10.xml
+    fe="scale(lat,10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_10.xml.1.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:375: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:375"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:375"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:375: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:375"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:375"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_168
+#AT_START_169
+at_fn_group_banner 169 'DMRTest.at:376' \
+  "trans/receive dmr-testsuite/vol_1_ce_10.xml scale(lat,10);scale(lon,10) " ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "169. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_10.xml
+    fe="scale(lat,10);scale(lon,10)"
+    ce=""
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_10.xml.2.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:376: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:376"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:376"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:376: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:376"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:376"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_169
+#AT_START_170
+at_fn_group_banner 170 'DMRTest.at:377' \
+  "trans/receive dmr-testsuite/vol_1_ce_10.xml scale(lat,10);scale(lon,10) lat[10:11][10:11];lon[10:11][10:11]" ""
+at_xfail=no
+      test "Xpass" = "Xxfail" && at_xfail=yes
+(
+  $as_echo "170. $at_setup_line: testing $at_desc ..."
+  $at_traceon
+
+
+
+    input=$abs_srcdir/dmr-testsuite/vol_1_ce_10.xml
+    fe="scale(lat,10);scale(lon,10)"
+    ce="lat[10:11][10:11];lon[10:11][10:11]"
+    baseline=$abs_srcdir/dmr-testsuite/vol_1_ce_10.xml.3.func_base
+    # This doesn't work for some reason. jhrg 3/13/14 expect="pass"
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:377: \$abs_builddir/dmr-test -x -t \$input -f \"\$fe\" -c \"\$ce\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dmr-test -x -t $input -f \"$fe\" -c \"$ce\" || true" "DMRTest.at:377"
+( $at_check_trace; $abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:377"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/DMRTest.at:377: diff -b -B \$baseline stdout || diff -b -B \$baseline stderr"
+at_fn_check_prepare_dynamic "diff -b -B $baseline stdout || diff -b -B $baseline stderr" "DMRTest.at:377"
+( $at_check_trace; diff -b -B $baseline stdout || diff -b -B $baseline stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/DMRTest.at:377"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_170
diff --git a/tests/DMRTest.at b/tests/DMRTest.at
new file mode 100644
index 0000000..0e66303
--- /dev/null
+++ b/tests/DMRTest.at
@@ -0,0 +1,380 @@
+# Process with autom4te to create an -*- Autotest -*- test suite.
+
+AT_INIT([dmr-test])
+
+AT_ARG_OPTION_ARG([generate_parse],
+    [--generate_parse=arg   Build the baseline file for parser test 'arg'],
+    [echo "./dmr-test -x -p $at_arg_generate_parse > $at_arg_generate_parse.baseline 2>&1";
+     ./dmr-test -x -p $at_arg_generate_parse > $at_arg_generate_parse.baseline 2>&1;
+     echo "Built baseline for $at_arg_generate_parse";
+     exit],[])
+
+AT_ARG_OPTION_ARG([generate_trans],
+    [--generate_trans=arg  Build the baseline file for round trip transmission test 'arg'],
+    [echo "./dmr-test -x -t $at_arg_generate_trans > $at_arg_generate_trans.trans_base 2>&1";
+     ./dmr-test -x -t $at_arg_generate_trans > $at_arg_generate_trans.trans_base 2>&1;
+     echo "Built baseline for $at_arg_generate_trans";
+     exit],[])
+
+AT_ARG_OPTION_ARG([generate_trans_ce],
+    [--generate_trans_ce=dataset,ce,ext  Build the baseline (ext) file for round trip transmission test 'arg' with 'ce'],
+    [data=`echo $at_arg_generate_trans_ce | sed 's@\(.*\),\(.*\),\(.*\)@\1 at g'`
+     ce=`echo $at_arg_generate_trans_ce | sed 's@\(.*\),\(.*\),\(.*\)@\2 at g'`
+     code=`echo $at_arg_generate_trans_ce | sed 's@\(.*\),\(.*\),\(.*\)@\3 at g'`
+     echo "./dmr-test -x -t $data -c $ce > $data.$code.trans_base 2>&1";
+     ./dmr-test -x -t $data -c "$ce" > $data.$code.trans_base 2>&1;
+     echo "Built baseline for $at_arg_generate_trans_ce";
+     exit],[])
+
+# There is no easy way to write a --generate... option for the function expression
+# tests. Better to do it by hand... Use ... .num.func_base as the extension for the
+# baselines.
+ 
+# Usage DMR_PARSE $1 <test_input> $2 <pass/xfail>
+# The baseline is assumed to be $1.baseline
+m4_define([DMR_PARSE], [
+
+    AT_SETUP([parse $1])
+    AT_KEYWORDS([parse])
+    
+    input=$abs_srcdir/$1
+    baseline=$input.baseline
+    
+    AT_CHECK([$abs_builddir/dmr-test -x -p $input || true], [], [stdout], [stderr])
+    AT_CHECK([diff -b -B $baseline stdout || diff -b -B $baseline stderr], [], [ignore],[],[])
+    AT_XFAIL_IF([test "$2" = "xfail"])
+    
+    AT_CLEANUP
+])
+
+# Usage DMR_TRANS $1 <test_input> $2 <pass/xfail>
+# This code tests the values printed when the received document is decoded.
+m4_define([DMR_TRANS], [
+    # Test transmitting data (i.e., writing the Data DMR to a file and then decoding it)
+    AT_SETUP([trans/receive $1])
+    AT_KEYWORDS([trans])
+    
+    input=$abs_srcdir/$1
+    baseline=$input.trans_base
+
+    AT_CHECK([$abs_builddir/dmr-test -x -t $input || true], [], [stdout], [stderr])
+    AT_CHECK([diff -b -B $baseline stdout || diff -b -B $baseline stderr], [], [ignore],[],[])
+    
+    AT_XFAIL_IF([test "$2" = "xfail"])
+    AT_CLEANUP
+])
+
+# Usage DMR_TRANS_CE <test_input> <ce> <baseline> <pass/xfail>
+# This code tests the values printed when the received document is decoded.
+m4_define([DMR_TRANS_CE], [
+    # Test transmitting data (i.e., writing the Data DMR to a file and then decoding it)
+    # after applying a constraint expression to the source DMR.
+    AT_SETUP([trans/receive $1 $2])
+    AT_KEYWORDS([trans])
+    
+    input=$abs_srcdir/$1
+    baseline=$abs_srcdir/$3
+    
+    # echo "baseline: $baseline"
+
+    AT_CHECK([$abs_builddir/dmr-test -x -t $input -c "$2" || true], [], [stdout], [stderr])
+    AT_CHECK([diff -b -B $baseline stdout || diff -b -B $baseline stderr], [], [ignore],[],[])
+    
+    AT_XFAIL_IF([test "X$4" = "Xxfail"])
+    AT_CLEANUP
+])
+
+# Usage DMR_TRANS_FUNC_CE <test_input> <func expr> <ce> <baseline> <pass/xfail>
+# This code tests the values printed when the received document is decoded.
+m4_define([DMR_TRANS_FUNC_CE], [
+    # Test transmitting data (i.e., writing the Data DMR to a file and then decoding it)
+    # after applying a function and constraint expression to the source DMR. If either
+    # the function or constraint are empty strings, they will be ignored.
+    AT_SETUP([trans/receive $1 $2 $3])
+    AT_KEYWORDS([trans])
+    
+    input=$abs_srcdir/$1
+    fe="$2"
+    ce="$3"
+    baseline=$abs_srcdir/$4
+    # This doesn't work for some reason. jhrg 3/13/14 expect="$5"
+    
+    AT_CHECK([$abs_builddir/dmr-test -x -t $input -f "$fe" -c "$ce" || true], [], [stdout], [stderr])
+    AT_CHECK([diff -b -B $baseline stdout || diff -b -B $baseline stderr], [], [ignore],[],[])
+    
+    AT_XFAIL_IF([test "X$5" = "Xxfail"])
+
+    AT_CLEANUP
+])
+
+# Usage DMR_INTERN $1 <test_input> $2 <pass/xfail>
+# This code tests the values printed when the received document is decoded.
+m4_define([DMR_INTERN], [
+    # Test reading/interning data (i.e., using the read() methods to load up objects with
+    # values without running them through serialize/deserialize)
+    AT_SETUP([intern data $1])
+    AT_KEYWORDS([intern])
+    
+    input=$abs_srcdir/$1
+    baseline=$input.trans_base
+
+    AT_CHECK([$abs_builddir/dmr-test -x -i $input || true], [], [stdout], [stderr])
+    AT_CHECK([diff -b -B $baseline stdout || diff -b -B $baseline stderr], [], [ignore],[],[])
+    
+    AT_XFAIL_IF([test "$2" = "xfail"])
+    AT_CLEANUP
+])
+
+DMR_PARSE([dmr-testsuite/test_simple_1.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_2.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_3.xml], [pass])
+
+DMR_PARSE([dmr-testsuite/test_simple_3_error_1.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_3_error_2.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_3_error_3.xml], [pass])
+
+DMR_PARSE([dmr-testsuite/test_simple_4.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_5.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_6.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_7.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_8.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_9.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_9.1.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_simple_10.xml], [pass])
+
+DMR_PARSE([dmr-testsuite/test_array_1.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_array_2.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_array_3.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_array_4.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_array_5.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_array_6.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_array_7.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_array_8.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_array_10.xml], [pass])
+DMR_PARSE([dmr-testsuite/test_array_11.xml], [pass])
+
+# Transmit: Test building and then decoding the response
+
+DMR_TRANS([dmr-testsuite/test_simple_1.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_simple_2.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_simple_3.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_simple_4.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_simple_5.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_simple_6.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_simple_7.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_simple_8.xml], [xfail])
+DMR_TRANS([dmr-testsuite/test_simple_9.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_simple_9.1.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_simple_10.xml], [pass])
+
+DMR_TRANS([dmr-testsuite/test_array_1.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_array_2.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_array_3.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_array_4.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_array_5.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_array_6.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_array_7.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_array_8.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_array_10.xml], [pass])
+DMR_TRANS([dmr-testsuite/test_array_11.xml], [pass])
+
+DMR_INTERN([dmr-testsuite/test_simple_1.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_2.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_3.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_4.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_5.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_6.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_7.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_8.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_9.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_9.1.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_simple_10.xml], [pass])
+
+DMR_INTERN([dmr-testsuite/test_array_1.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_array_2.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_array_3.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_array_4.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_array_5.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_array_6.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_array_7.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_array_8.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_array_10.xml], [pass])
+DMR_INTERN([dmr-testsuite/test_array_11.xml], [pass])
+
+# Test various factes of the CE parser and evaluation engine
+
+DMR_TRANS_CE([dmr-testsuite/test_array_4.xml], [a], [dmr-testsuite/test_array_4.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_4.xml], [a[[]][[]] ], [dmr-testsuite/test_array_4.xml.1.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_4.xml], [/row=[[0:1]];/col=[[3]];a],  [dmr-testsuite/test_array_4.xml.3.trans_base], [pass])
+    
+DMR_TRANS_CE([dmr-testsuite/test_array_4.xml], [/row=[[0:1]];/col=[[3]];a[[]][[]] ],  [dmr-testsuite/test_array_4.xml.4.trans_base], [pass])
+    
+DMR_TRANS_CE([dmr-testsuite/test_array_4.xml], [/row=[[0:1]];/col=[[3]];a[[]][[]];b[[0]][[]];c[[0:]][[0:]] ],  [dmr-testsuite/test_array_4.xml.5.trans_base], [pass])
+    
+DMR_TRANS_CE([dmr-testsuite/test_array_4.xml], [x[[]][[]] ], [dmr-testsuite/test_array_4.xml.6.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_4.xml], [/row=[[0:1]];x[[]][[]] ], [dmr-testsuite/test_array_4.xml.7.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_4.xml], [c[[2:]][[2:]] ], [dmr-testsuite/test_array_4.xml.8.trans_base], [pass])
+    
+DMR_TRANS_CE([dmr-testsuite/test_simple_6.xml], [s], [dmr-testsuite/test_simple_6.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_simple_6.xml], [s.i1], [dmr-testsuite/test_simple_6.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_simple_6.xml], [s.s], [dmr-testsuite/test_simple_6.xml.3.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_simple_6.1.xml], [s.inner.i2], [dmr-testsuite/test_simple_6.1.xml.1.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_simple_6.xml], [s{i1}], [dmr-testsuite/test_simple_6.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_simple_6.xml], [s{s}], [dmr-testsuite/test_simple_6.xml.3.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_simple_6.1.xml], [s{inner.i2}], [dmr-testsuite/test_simple_6.1.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_simple_6.1.xml], [s{inner{i2}}], [dmr-testsuite/test_simple_6.1.xml.1.trans_base], [pass])
+
+# test_array_6 holds a 2D array of Structure
+DMR_TRANS_CE([dmr-testsuite/test_array_6.xml], [a], [dmr-testsuite/test_array_6.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.xml], [a[[]][[]] ], [dmr-testsuite/test_array_6.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.xml], [/row=[[0:1]];a[[]][[]] ], [dmr-testsuite/test_array_6.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.xml], [/row=[[0:1]];a[[]][[1:2]] ], [dmr-testsuite/test_array_6.xml.3.trans_base], [pass])
+
+# test_array holds a Structure that has a 2D array for a field
+DMR_TRANS_CE([dmr-testsuite/test_array_6.2.xml], [a], [dmr-testsuite/test_array_6.2.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.2.xml], [a{i;j}], [dmr-testsuite/test_array_6.2.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.2.xml], [a.i], [dmr-testsuite/test_array_6.2.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.2.xml], [a{i}], [dmr-testsuite/test_array_6.2.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.2.xml], [a.i[[0]][[1:2]] ], [dmr-testsuite/test_array_6.2.xml.3.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.2.xml], [a{i[[0]][[1:2]]} ], [dmr-testsuite/test_array_6.2.xml.3.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.2.xml], [/row=[[0:1]];a.i[[]][[1:2]] ], [dmr-testsuite/test_array_6.2.xml.4.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.2.xml], [/row=[[0:1]];a{i[[]][[1:2]]} ], [dmr-testsuite/test_array_6.2.xml.4.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_6.2.xml], [a.j], [dmr-testsuite/test_array_6.2.xml.5.trans_base], [pass])
+
+# test_array_6.1 is an array of Structure that holds an array and a scalar
+DMR_TRANS_CE([dmr-testsuite/test_array_6.1.xml], [a], [dmr-testsuite/test_array_6.1.xml.1.trans_base], [pass])
+
+# slice the structure but not the field
+DMR_TRANS_CE([dmr-testsuite/test_array_6.1.xml], [/row=[[1:2]];a[[]][[0]] ], [dmr-testsuite/test_array_6.1.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.1.xml], [/row=[[1:2]];a[[]][[0]]{i;j} ], [dmr-testsuite/test_array_6.1.xml.2.trans_base], [pass])
+# Do we really need the FQN?
+DMR_TRANS_CE([dmr-testsuite/test_array_6.1.xml], [row=[[1:2]];a[[]][[0]]{i;j} ], [dmr-testsuite/test_array_6.1.xml.2.trans_base], [pass])
+
+# slice the field but not the structure
+DMR_TRANS_CE([dmr-testsuite/test_array_6.1.xml], [a{i[[1:2]][[1:3]];j} ], [dmr-testsuite/test_array_6.1.xml.3.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_6.1.xml], [a[[]][[]]{i[[1:2]][[1:3]];j} ], [dmr-testsuite/test_array_6.1.xml.3.trans_base], [pass])
+
+# slice both the structure and the array it contains using both the shared dim and 
+# a local slice for each
+DMR_TRANS_CE([dmr-testsuite/test_array_6.1.xml], [/row=[[1]];a[[]][[0]]{i[[]][[0:1]]} ], [dmr-testsuite/test_array_6.1.xml.4.trans_base], [pass])
+
+# Test sequences and arrays of sequences
+DMR_TRANS_CE([dmr-testsuite/test_simple_7.xml], [s], [dmr-testsuite/test_simple_7.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_simple_7.xml], [s{i1;s}], [dmr-testsuite/test_simple_7.xml.1.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_simple_7.xml], [s.i1], [dmr-testsuite/test_simple_7.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_simple_7.xml], [s{i1}], [dmr-testsuite/test_simple_7.xml.2.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_simple_8.xml], [outer], [dmr-testsuite/test_simple_8.xml.1.trans_base], [xfail])
+DMR_TRANS_CE([dmr-testsuite/test_simple_8.xml], [outer.s.s], [dmr-testsuite/test_simple_8.xml.2.trans_base], [xfail])
+DMR_TRANS_CE([dmr-testsuite/test_simple_8.xml], [outer{s{s}}], [dmr-testsuite/test_simple_8.xml.2.trans_base], [xfail])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.xml], [s], [dmr-testsuite/test_array_7.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.xml], [s{i1;s}], [dmr-testsuite/test_array_7.xml.1.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.xml], [s.i1], [dmr-testsuite/test_array_7.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.xml], [s{i1}], [dmr-testsuite/test_array_7.xml.2.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.xml], [s[[1]] ], [dmr-testsuite/test_array_7.xml.3.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.xml], [s[[1]]{i1;s}], [dmr-testsuite/test_array_7.xml.3.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.xml], [s[[1]]{i1}], [dmr-testsuite/test_array_7.xml.4.trans_base], [pass])
+
+# test_array_8 has a 2D Sequence that uses a shared dim
+DMR_TRANS_CE([dmr-testsuite/test_array_8.xml], [/col=[[1:2]];s[[1]][[]]{i1}], [dmr-testsuite/test_array_8.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_8.xml], [col=[[1:2]];s[[1]][[]]{i1}], [dmr-testsuite/test_array_8.xml.1.trans_base], [pass])
+
+# test_array_7.1 holds a sequence that has an array for one of its fields
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [], [dmr-testsuite/test_array_7.1.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [s], [dmr-testsuite/test_array_7.1.xml.1.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [s.i1], [dmr-testsuite/test_array_7.1.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [s.i1[[]][[]] ], [dmr-testsuite/test_array_7.1.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [s{i1}], [dmr-testsuite/test_array_7.1.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [s{i1[[]][[]]} ], [dmr-testsuite/test_array_7.1.xml.2.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [s.i1[[0]][[0]] ], [dmr-testsuite/test_array_7.1.xml.3.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [s{i1[[0]][[0]]} ], [dmr-testsuite/test_array_7.1.xml.3.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [s.i1[[0:2]][[1:2]] ], [dmr-testsuite/test_array_7.1.xml.4.trans_base], [pass])
+
+# Should this CE be supported? jhrg 12/23/13
+# DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [/row=[[2:3]];/col=[[2:3]] ], [dmr-testsuite/test_array_7.1.xml.5.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [/row=[[2:3]];/col=[[2:3]];s ], [dmr-testsuite/test_array_7.1.xml.5.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [/row=[[2:3]];/col=[[2:3]];s.i1 ], [dmr-testsuite/test_array_7.1.xml.6.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [/row=[[2:3]];/col=[[2:3]];s.i1[[]][[]] ], [dmr-testsuite/test_array_7.1.xml.6.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [/row=[[2:3]];/col=[[2:3]];s{i1} ], [dmr-testsuite/test_array_7.1.xml.6.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.1.xml], [/row=[[2:3]];/col=[[2:3]];s{i1[[]][[]]} ], [dmr-testsuite/test_array_7.1.xml.6.trans_base], [pass])
+
+# test_array_7.2 is a sequence array that holds an array as one of its fields
+DMR_TRANS_CE([dmr-testsuite/test_array_7.2.xml], [/col=[[1:2]];s[[]]{i1}], [dmr-testsuite/test_array_7.2.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.2.xml], [/col=[[1:2]];s[[]]{i1[[]][[]]}], [dmr-testsuite/test_array_7.2.xml.1.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.2.xml], [/col=[[1:2]];s{i1[[]][[]]}], [dmr-testsuite/test_array_7.2.xml.1.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.2.xml], [/col=[[1:2]];s[[]]{i1[[0]][[]]}], [dmr-testsuite/test_array_7.2.xml.2.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.2.xml], [/col=[[1:2]];s{i1[[0]][[]]}], [dmr-testsuite/test_array_7.2.xml.2.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.2.xml], [/col=[[1:2]];s[[0]]{i1}], [dmr-testsuite/test_array_7.2.xml.3.trans_base], [pass])
+DMR_TRANS_CE([dmr-testsuite/test_array_7.2.xml], [/col=[[1:2]];s[[0]]{i1[[]][[]]}], [dmr-testsuite/test_array_7.2.xml.3.trans_base], [pass])
+
+DMR_TRANS_CE([dmr-testsuite/test_array_7.2.xml], [/col=[[1:2]];s[[0]]{i1[[0]][[]]}], [dmr-testsuite/test_array_7.2.xml.4.trans_base], [pass])
+
+# Test the function parser and evaluator. The function 'scale' is defined 
+# for both DAP2 and DAP4 in D4TestFunction.cc/h
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_1.xml], [scale(x,1)], [], [dmr-testsuite/test_array_1.xml.1.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_1.xml], [scale(x,10)], [], [dmr-testsuite/test_array_1.xml.2.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_1.xml], [scale(x,-10)], [], [dmr-testsuite/test_array_1.xml.3.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_1.xml], [scale(x,0.001)], [], [dmr-testsuite/test_array_1.xml.4.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_1.xml], [scale(x,-0.001)], [], [dmr-testsuite/test_array_1.xml.5.func_base], [pass])
+
+# Test the largest signed int64 value (it will be stored in a D4RValue that 
+# holds a Int64 variable).
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_1.xml], [scale(x,0x7fffffffffffffff)], [], [dmr-testsuite/test_array_1.xml.6.func_base], [pass])
+# This only fits in a unsigned long long (DAP4's UInt64)
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_1.xml], [scale(x,0x8fffffffffffffff)], [], [dmr-testsuite/test_array_1.xml.7.func_base], [pass])
+
+# test_array_5 has 64 bit ints in c and d; a and b are Int8 and UInt8 types
+# all of these test arrays that use named dimensions
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_5.xml], [scale(a,0.001)], [], [dmr-testsuite/test_array_5.xml.1.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_5.xml], [scale(b,0.001)], [], [dmr-testsuite/test_array_5.xml.2.func_base], [pass])
+
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_5.xml], [scale(c,0.001)], [], [dmr-testsuite/test_array_5.xml.3.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/test_array_5.xml], [scale(d,0.001)], [], [dmr-testsuite/test_array_5.xml.4.func_base], [pass])
+
+# Use the vol_1_ce_* datasets for tests
+
+# Test using variables for source values and functional composition
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(u,10)], [], [dmr-testsuite/vol_1_ce_1.xml.1.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(u,v)], [], [dmr-testsuite/vol_1_ce_1.xml.2.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(scale(u,10),0.01)], [], [dmr-testsuite/vol_1_ce_1.xml.3.func_base], [pass])
+
+# Test name parsing for Structure members
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(Point.x,10)], [], [dmr-testsuite/vol_1_ce_1.xml.4.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(Point.x,Point.y)], [], [dmr-testsuite/vol_1_ce_1.xml.5.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(scale(Point.x,10),0.01)], [], [dmr-testsuite/vol_1_ce_1.xml.6.func_base], [pass])
+
+# Test the 'array constant' special form (we need a dataset only because the parser needs a DMR to run)
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$Byte(20:1,2,3,4),10)], [], [dmr-testsuite/vol_1_ce_1.xml.7.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$Int8(20:10,11,12,-9),10)], [], [dmr-testsuite/vol_1_ce_1.xml.8.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$UInt16(20:1,2,3,4),10)], [], [dmr-testsuite/vol_1_ce_1.xml.9.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$Int16(20:1,2,3,-4),10)], [], [dmr-testsuite/vol_1_ce_1.xml.10.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$UInt32(20:1,2,3,4),10)], [], [dmr-testsuite/vol_1_ce_1.xml.11.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$Int32(20:1,2,3,-4),10)], [], [dmr-testsuite/vol_1_ce_1.xml.12.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$UInt64(20:1,2,3,0xffffffffffffffff),1)], [], [dmr-testsuite/vol_1_ce_1.xml.13.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$Int64(20:1,2,3,0x7fffffffffffffff),1)], [], [dmr-testsuite/vol_1_ce_1.xml.14.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$Float32(20:1,2,3,4.55),10)], [], [dmr-testsuite/vol_1_ce_1.xml.15.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_1.xml], [scale(\$Float64(20:1,2,3,4.55),10)], [], [dmr-testsuite/vol_1_ce_1.xml.16.func_base], [pass])
+
+# Test a sequence of function calls and the application of a Constraint to 
+# a function result
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_10.xml], [scale(lat,10)], [], [dmr-testsuite/vol_1_ce_10.xml.1.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_10.xml], [scale(lat,10);scale(lon,10)], [], [dmr-testsuite/vol_1_ce_10.xml.2.func_base], [pass])
+DMR_TRANS_FUNC_CE([dmr-testsuite/vol_1_ce_10.xml], [scale(lat,10);scale(lon,10)], [lat[[10:11]][[10:11]];lon[[10:11]][[10:11]]], [dmr-testsuite/vol_1_ce_10.xml.3.func_base], [pass])
+
+
+
diff --git a/tests/EXPRTest b/tests/EXPRTest
index 353e429..515b539 100755
--- a/tests/EXPRTest
+++ b/tests/EXPRTest
@@ -616,86 +616,98 @@ at_help_all="1;EXPRTest.at:45;expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k
 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:102;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass);expr;
-106;EXPRTest.at:102;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass);expr;
+27;EXPRTest.at:68;expr-test -b -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass);expr;
+28;EXPRTest.at:71;expr-test -b -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass);expr;
+29;EXPRTest.at:77;expr-test -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' (pass);expr;
+30;EXPRTest.at:77;expr-test -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' (pass);expr;
+31;EXPRTest.at:79;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass);expr;
+32;EXPRTest.at:79;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass);expr;
+33;EXPRTest.at:80;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:80;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:81;expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i (pass);expr;
+36;EXPRTest.at:81;expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i (pass);expr;
+37;EXPRTest.at:82;expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass);expr;
+38;EXPRTest.at:82;expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass);expr;
+39;EXPRTest.at:83;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass);expr;
+40;EXPRTest.at:83;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass);expr;
+41;EXPRTest.at:84;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length (pass);expr;
+42;EXPRTest.at:84;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length (pass);expr;
+43;EXPRTest.at:85;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass);expr;
+44;EXPRTest.at:85;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass);expr;
+45;EXPRTest.at:86;expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k j,o (pass);expr;
+46;EXPRTest.at:86;expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k j,o (pass);expr;
+47;EXPRTest.at:87;expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" (pass);expr;
+48;EXPRTest.at:87;expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" (pass);expr;
+49;EXPRTest.at:88;expr-test -w \$abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass);expr;
+50;EXPRTest.at:88;expr-test -W \$abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass);expr;
+51;EXPRTest.at:89;expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" (pass);expr;
+52;EXPRTest.at:89;expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" (pass);expr;
+53;EXPRTest.at:90;expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" (pass);expr;
+54;EXPRTest.at:90;expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" (pass);expr;
+55;EXPRTest.at:91;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:91;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:92;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass);expr;
+58;EXPRTest.at:92;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass);expr;
+59;EXPRTest.at:93;expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass);expr;
+60;EXPRTest.at:93;expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass);expr;
+61;EXPRTest.at:97;expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i,2\\) (pass);expr;
+62;EXPRTest.at:97;expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i,2\\) (pass);expr;
+63;EXPRTest.at:98;expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i[2:4][3:6],2\\) (pass);expr;
+64;EXPRTest.at:98;expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i[2:4][3:6],2\\) (pass);expr;
+65;EXPRTest.at:100;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k scale\\(i[3],2\\) (pass);expr;
+66;EXPRTest.at:100;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k scale\\(i[3],2\\) (pass);expr;
+67;EXPRTest.at:102;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k scale\\(j,2\\) (pass);expr;
+68;EXPRTest.at:102;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k scale\\(j,2\\) (pass);expr;
+69;EXPRTest.at:104;expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass);expr;
+70;EXPRTest.at:104;expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass);expr;
+71;EXPRTest.at:105;expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass);expr;
+72;EXPRTest.at:105;expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass);expr;
+73;EXPRTest.at:106;expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass);expr;
+74;EXPRTest.at:106;expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass);expr;
+75;EXPRTest.at:107;expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass);expr;
+76;EXPRTest.at:107;expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass);expr;
+77;EXPRTest.at:108;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass);expr;
+78;EXPRTest.at:108;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass);expr;
+79;EXPRTest.at:109;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass);expr;
+80;EXPRTest.at:109;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass);expr;
+81;EXPRTest.at:110;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass);expr;
+82;EXPRTest.at:110;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass);expr;
+83;EXPRTest.at:111;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass);expr;
+84;EXPRTest.at:111;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass);expr;
+85;EXPRTest.at:112;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass);expr;
+86;EXPRTest.at:112;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass);expr;
+87;EXPRTest.at:113;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass);expr;
+88;EXPRTest.at:113;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass);expr;
+89;EXPRTest.at:114;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass);expr;
+90;EXPRTest.at:114;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass);expr;
+91;EXPRTest.at:115;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass);expr;
+92;EXPRTest.at:115;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass);expr;
+93;EXPRTest.at:116;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass);expr;
+94;EXPRTest.at:116;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass);expr;
+95;EXPRTest.at:117;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass);expr;
+96;EXPRTest.at:117;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass);expr;
+97;EXPRTest.at:118;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass);expr;
+98;EXPRTest.at:118;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass);expr;
+99;EXPRTest.at:119;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass);expr;
+100;EXPRTest.at:119;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass);expr;
+101;EXPRTest.at:120;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass);expr;
+102;EXPRTest.at:120;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass);expr;
+103;EXPRTest.at:121;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass);expr;
+104;EXPRTest.at:121;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass);expr;
+105;EXPRTest.at:123;expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k i (pass);expr;
+106;EXPRTest.at:123;expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k i (pass);expr;
+107;EXPRTest.at:124;expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass);expr;
+108;EXPRTest.at:124;expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass);expr;
+109;EXPRTest.at:125;expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass);expr;
+110;EXPRTest.at:125;expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass);expr;
+111;EXPRTest.at:126;expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass);expr;
+112;EXPRTest.at:126;expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass);expr;
+113;EXPRTest.at:127;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass);expr;
+114;EXPRTest.at:127;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass);expr;
+115;EXPRTest.at:129;expr-test -b -w \$abs_srcdir/expr-testsuite/test.f -k \"\" (pass);expr;
+116;EXPRTest.at:129;expr-test -b -W \$abs_srcdir/expr-testsuite/test.f -k \"\" (pass);expr;
+117;EXPRTest.at:130;expr-test -b -w \$abs_srcdir/expr-testsuite/test.f -k \"&i<3000\" (pass);expr;
+118;EXPRTest.at:130;expr-test -b -W \$abs_srcdir/expr-testsuite/test.f -k \"&i<3000\" (pass);expr;
 "
 # List of the all the test groups.
 at_groups_all=`$as_echo "$at_help_all" | sed 's/;.*//'`
@@ -709,7 +721,7 @@ at_fn_validate_ranges ()
   for at_grp
   do
     eval at_value=\$$at_grp
-    if test $at_value -lt 1 || test $at_value -gt 106; then
+    if test $at_value -lt 1 || test $at_value -gt 118; then
       $as_echo "invalid test group: $at_value" >&2
       exit 1
     fi
@@ -1007,7 +1019,7 @@ fi
 # List of tests.
 if $at_list_p; then
   cat <<_ATEOF || at_write_fail=1
-libdap 3.12.0 test suite: expr-test test groups:
+libdap 3.14.0 test suite: expr-test test groups:
 
  NUM: FILE-NAME:LINE     TEST-GROUP-NAME
       KEYWORDS
@@ -1048,7 +1060,7 @@ _ATEOF
   exit $at_write_fail
 fi
 if $at_version_p; then
-  $as_echo "$as_me (libdap 3.12.0)" &&
+  $as_echo "$as_me (libdap 3.14.0)" &&
   cat <<\_ATEOF || at_write_fail=1
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1225,11 +1237,11 @@ exec 5>>"$at_suite_log"
 
 # Banners and logs.
 $as_echo "## ------------------------------------ ##
-## libdap 3.12.0 test suite: expr-test. ##
+## libdap 3.14.0 test suite: expr-test. ##
 ## ------------------------------------ ##"
 {
   $as_echo "## ------------------------------------ ##
-## libdap 3.12.0 test suite: expr-test. ##
+## libdap 3.14.0 test suite: expr-test. ##
 ## ------------------------------------ ##"
   echo
 
@@ -2073,7 +2085,7 @@ _ASBOX
   $as_echo "Please send $at_msg and all information you think might help:
 
    To: <opendap-tech at opendap.org>
-   Subject: [libdap 3.12.0] $as_me: $at_fail_list${at_fail_list:+ failed${at_xpass_list:+, }}$at_xpass_list${at_xpass_list:+ passed unexpectedly}
+   Subject: [libdap 3.14.0] $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
@@ -3388,8 +3400,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_26
 #AT_START_27
-at_fn_group_banner 27 'EXPRTest.at:61' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass)" ""
+at_fn_group_banner 27 'EXPRTest.at:68' \
+  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -3406,28 +3418,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:68: \$abs_builddir/expr-test -b -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 -b -w $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' -f \"dummy\" || true" "EXPRTest.at:68"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 3"' -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:68: 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:68"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:68"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3438,8 +3450,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_27
 #AT_START_28
-at_fn_group_banner 28 'EXPRTest.at:61' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass)" ""
+at_fn_group_banner 28 'EXPRTest.at:71' \
+  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -3456,28 +3468,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:71: \$abs_builddir/expr-test -b -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 -b -W $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' -f \"dummy\" || true" "EXPRTest.at:71"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 3"' -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:71: 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:71"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:71"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3488,7 +3500,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_28
 #AT_START_29
-at_fn_group_banner 29 'EXPRTest.at:62' \
+at_fn_group_banner 29 'EXPRTest.at:77' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3506,28 +3518,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:77: \$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:77"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:77: 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:77"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:77"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3538,7 +3550,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_29
 #AT_START_30
-at_fn_group_banner 30 'EXPRTest.at:62' \
+at_fn_group_banner 30 'EXPRTest.at:77' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3556,28 +3568,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:77: \$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:77"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:77: 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:77"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:77"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3588,7 +3600,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_30
 #AT_START_31
-at_fn_group_banner 31 'EXPRTest.at:63' \
+at_fn_group_banner 31 'EXPRTest.at:79' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3606,28 +3618,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:79: \$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:79"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:79: 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:79"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:79"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3638,7 +3650,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_31
 #AT_START_32
-at_fn_group_banner 32 'EXPRTest.at:63' \
+at_fn_group_banner 32 'EXPRTest.at:79' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3656,28 +3668,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:79: \$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:79"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:79: 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:79"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:79"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3688,7 +3700,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_32
 #AT_START_33
-at_fn_group_banner 33 'EXPRTest.at:64' \
+at_fn_group_banner 33 'EXPRTest.at:80' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3706,28 +3718,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:80: \$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:80"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:80: 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:80"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:80"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3738,7 +3750,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_33
 #AT_START_34
-at_fn_group_banner 34 'EXPRTest.at:64' \
+at_fn_group_banner 34 'EXPRTest.at:80' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3756,28 +3768,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:80: \$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:80"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:80: 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:80"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:80"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3788,7 +3800,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_34
 #AT_START_35
-at_fn_group_banner 35 'EXPRTest.at:65' \
+at_fn_group_banner 35 'EXPRTest.at:81' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3806,28 +3818,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:81: \$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:81"
 ( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:81: 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:81"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:81"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3838,7 +3850,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_35
 #AT_START_36
-at_fn_group_banner 36 'EXPRTest.at:65' \
+at_fn_group_banner 36 'EXPRTest.at:81' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3856,28 +3868,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:81: \$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:81"
 ( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:81: 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:81"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:81"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3888,7 +3900,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_36
 #AT_START_37
-at_fn_group_banner 37 'EXPRTest.at:66' \
+at_fn_group_banner 37 'EXPRTest.at:82' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3906,28 +3918,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:82: \$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:82"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:82: 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:82"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:82"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3938,7 +3950,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_37
 #AT_START_38
-at_fn_group_banner 38 'EXPRTest.at:66' \
+at_fn_group_banner 38 'EXPRTest.at:82' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -3956,28 +3968,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:82: \$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:82"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:82: 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:82"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:82"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -3988,7 +4000,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_38
 #AT_START_39
-at_fn_group_banner 39 'EXPRTest.at:67' \
+at_fn_group_banner 39 'EXPRTest.at:83' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4006,28 +4018,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:83: \$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:83"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:83: 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:83"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:83"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4038,7 +4050,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_39
 #AT_START_40
-at_fn_group_banner 40 'EXPRTest.at:67' \
+at_fn_group_banner 40 'EXPRTest.at:83' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4056,28 +4068,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:83: \$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:83"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:83: 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:83"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:83"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4088,7 +4100,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_40
 #AT_START_41
-at_fn_group_banner 41 'EXPRTest.at:68' \
+at_fn_group_banner 41 'EXPRTest.at:84' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4106,28 +4118,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:84: \$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:84"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:84: 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:84"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:84"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4138,7 +4150,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_41
 #AT_START_42
-at_fn_group_banner 42 'EXPRTest.at:68' \
+at_fn_group_banner 42 'EXPRTest.at:84' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4156,28 +4168,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:84: \$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:84"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:84: 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:84"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:84"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4188,7 +4200,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_42
 #AT_START_43
-at_fn_group_banner 43 'EXPRTest.at:69' \
+at_fn_group_banner 43 'EXPRTest.at:85' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4206,28 +4218,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:85: \$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:85"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:85: 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:85"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:85"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4238,7 +4250,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_43
 #AT_START_44
-at_fn_group_banner 44 'EXPRTest.at:69' \
+at_fn_group_banner 44 'EXPRTest.at:85' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4256,28 +4268,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:85: \$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:85"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:85: 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:85"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:85"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4288,7 +4300,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_44
 #AT_START_45
-at_fn_group_banner 45 'EXPRTest.at:70' \
+at_fn_group_banner 45 'EXPRTest.at:86' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k j,o (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4306,28 +4318,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:86: \$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:86"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:86: 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:86"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:86"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4338,7 +4350,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_45
 #AT_START_46
-at_fn_group_banner 46 'EXPRTest.at:70' \
+at_fn_group_banner 46 'EXPRTest.at:86' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k j,o (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4356,28 +4368,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:86: \$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:86"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:86: 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:86"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:86"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4388,7 +4400,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_46
 #AT_START_47
-at_fn_group_banner 47 'EXPRTest.at:71' \
+at_fn_group_banner 47 'EXPRTest.at:87' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4406,28 +4418,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:87: \$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:87"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:87: 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:87"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:87"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4438,7 +4450,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_47
 #AT_START_48
-at_fn_group_banner 48 'EXPRTest.at:71' \
+at_fn_group_banner 48 'EXPRTest.at:87' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4456,28 +4468,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:87: \$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:87"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:87: 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:87"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:87"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4488,7 +4500,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_48
 #AT_START_49
-at_fn_group_banner 49 'EXPRTest.at:72' \
+at_fn_group_banner 49 'EXPRTest.at:88' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4506,28 +4518,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:88: \$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:88"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:88: 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:88"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:88"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4538,7 +4550,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_49
 #AT_START_50
-at_fn_group_banner 50 'EXPRTest.at:72' \
+at_fn_group_banner 50 'EXPRTest.at:88' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4556,28 +4568,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:88: \$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:88"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:88: 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:88"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:88"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4588,7 +4600,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_50
 #AT_START_51
-at_fn_group_banner 51 'EXPRTest.at:73' \
+at_fn_group_banner 51 'EXPRTest.at:89' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4606,28 +4618,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:89: \$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:89"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:89: 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:89"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:89"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4638,7 +4650,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_51
 #AT_START_52
-at_fn_group_banner 52 'EXPRTest.at:73' \
+at_fn_group_banner 52 'EXPRTest.at:89' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4656,28 +4668,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:89: \$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:89"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:89: 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:89"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:89"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4688,7 +4700,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_52
 #AT_START_53
-at_fn_group_banner 53 'EXPRTest.at:74' \
+at_fn_group_banner 53 'EXPRTest.at:90' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4706,28 +4718,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:90: \$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:90"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:90: 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:90"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:90"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4738,7 +4750,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_53
 #AT_START_54
-at_fn_group_banner 54 'EXPRTest.at:74' \
+at_fn_group_banner 54 'EXPRTest.at:90' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4756,28 +4768,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:90: \$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:90"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:90: 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:90"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:90"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4788,7 +4800,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_54
 #AT_START_55
-at_fn_group_banner 55 'EXPRTest.at:75' \
+at_fn_group_banner 55 'EXPRTest.at:91' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4806,28 +4818,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:91: \$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:91"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:91: 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:91"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:91"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4838,7 +4850,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_55
 #AT_START_56
-at_fn_group_banner 56 'EXPRTest.at:75' \
+at_fn_group_banner 56 'EXPRTest.at:91' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4856,28 +4868,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:91: \$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:91"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:91: 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:91"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:91"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4888,7 +4900,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_56
 #AT_START_57
-at_fn_group_banner 57 'EXPRTest.at:76' \
+at_fn_group_banner 57 'EXPRTest.at:92' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4906,28 +4918,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:92: \$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:92"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:92: 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:92"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:92"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4938,7 +4950,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_57
 #AT_START_58
-at_fn_group_banner 58 'EXPRTest.at:76' \
+at_fn_group_banner 58 'EXPRTest.at:92' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -4956,28 +4968,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:92: \$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:92"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:92: 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:92"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:92"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -4988,7 +5000,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_58
 #AT_START_59
-at_fn_group_banner 59 'EXPRTest.at:77' \
+at_fn_group_banner 59 'EXPRTest.at:93' \
   "expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -5006,28 +5018,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:93: \$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:93"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:93: 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:93"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:93"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5038,7 +5050,7 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_59
 #AT_START_60
-at_fn_group_banner 60 'EXPRTest.at:77' \
+at_fn_group_banner 60 'EXPRTest.at:93' \
   "expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
@@ -5056,28 +5068,28 @@ at_xfail=no
     # 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"
+$as_echo "$at_srcdir/EXPRTest.at:93: \$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:93"
 ( $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" 5>&-
 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_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: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"
+$as_echo "$at_srcdir/EXPRTest.at:93: 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:93"
 ( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:93"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5088,8 +5100,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_60
 #AT_START_61
-at_fn_group_banner 61 'EXPRTest.at:78' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass)" ""
+at_fn_group_banner 61 'EXPRTest.at:97' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i,2\\) (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5106,28 +5118,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:97: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i,2\\) -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k scale\\(i,2\\) -f \"dummy\" || true" "EXPRTest.at:97"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k scale\(i,2\) -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:97: diff -b -B \$abs_srcdir/expr-testsuite/test.6.func1.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6.func1.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6.func1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.func1.base stderr" "EXPRTest.at:97"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6.func1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.func1.base stderr
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:97"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5138,8 +5150,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_61
 #AT_START_62
-at_fn_group_banner 62 'EXPRTest.at:78' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass)" ""
+at_fn_group_banner 62 'EXPRTest.at:97' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i,2\\) (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5156,28 +5168,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:97: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i,2\\) -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k scale\\(i,2\\) -f \"dummy\" || true" "EXPRTest.at:97"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k scale\(i,2\) -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:97: diff -b -B \$abs_srcdir/expr-testsuite/test.6.func1.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6.func1.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6.func1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.func1.base stderr" "EXPRTest.at:97"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6.func1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.func1.base stderr
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:97"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5188,8 +5200,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_62
 #AT_START_63
-at_fn_group_banner 63 'EXPRTest.at:79' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass)" ""
+at_fn_group_banner 63 'EXPRTest.at:98' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i[2:4][3:6],2\\) (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5206,28 +5218,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:98: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i[2:4][3:6],2\\) -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k scale\\(i[2:4][3:6],2\\) -f \"dummy\" || true" "EXPRTest.at:98"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k scale\(i[2:4][3:6],2\) -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:98: diff -b -B \$abs_srcdir/expr-testsuite/test.6.func2.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6.func2.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6.func2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.func2.base stderr" "EXPRTest.at:98"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6.func2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.func2.base stderr
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:98"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5238,8 +5250,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_63
 #AT_START_64
-at_fn_group_banner 64 'EXPRTest.at:79' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass)" ""
+at_fn_group_banner 64 'EXPRTest.at:98' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i[2:4][3:6],2\\) (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5256,28 +5268,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:98: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k scale\\(i[2:4][3:6],2\\) -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k scale\\(i[2:4][3:6],2\\) -f \"dummy\" || true" "EXPRTest.at:98"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k scale\(i[2:4][3:6],2\) -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:98: diff -b -B \$abs_srcdir/expr-testsuite/test.6.func2.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6.func2.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6.func2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.func2.base stderr" "EXPRTest.at:98"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6.func2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.func2.base stderr
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:98"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5288,8 +5300,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_64
 #AT_START_65
-at_fn_group_banner 65 'EXPRTest.at:80' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass)" ""
+at_fn_group_banner 65 'EXPRTest.at:100' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k scale\\(i[3],2\\) (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5306,28 +5318,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:100: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k scale\\(i[3],2\\) -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k scale\\(i[3],2\\) -f \"dummy\" || true" "EXPRTest.at:100"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k scale\(i[3],2\) -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:100: diff -b -B \$abs_srcdir/expr-testsuite/test.5.func3.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5.func3.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5.func3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.func3.base stderr" "EXPRTest.at:100"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5.func3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.func3.base stderr
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:100"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5338,8 +5350,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_65
 #AT_START_66
-at_fn_group_banner 66 'EXPRTest.at:80' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass)" ""
+at_fn_group_banner 66 'EXPRTest.at:100' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k scale\\(i[3],2\\) (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5356,28 +5368,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:100: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k scale\\(i[3],2\\) -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k scale\\(i[3],2\\) -f \"dummy\" || true" "EXPRTest.at:100"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k scale\(i[3],2\) -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:100: diff -b -B \$abs_srcdir/expr-testsuite/test.5.func3.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5.func3.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5.func3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.func3.base stderr" "EXPRTest.at:100"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5.func3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.func3.base stderr
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:100"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5388,8 +5400,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_66
 #AT_START_67
-at_fn_group_banner 67 'EXPRTest.at:81' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass)" ""
+at_fn_group_banner 67 'EXPRTest.at:102' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k scale\\(j,2\\) (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5406,28 +5418,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:102: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k scale\\(j,2\\) -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k scale\\(j,2\\) -f \"dummy\" || true" "EXPRTest.at:102"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k scale\(j,2\) -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:102: diff -b -B \$abs_srcdir/expr-testsuite/test.5.func4.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5.func4.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5.func4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.func4.base stderr" "EXPRTest.at:102"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5.func4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.func4.base stderr
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:102"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5438,8 +5450,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_67
 #AT_START_68
-at_fn_group_banner 68 'EXPRTest.at:81' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass)" ""
+at_fn_group_banner 68 'EXPRTest.at:102' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k scale\\(j,2\\) (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5456,28 +5468,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:102: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k scale\\(j,2\\) -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k scale\\(j,2\\) -f \"dummy\" || true" "EXPRTest.at:102"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k scale\(j,2\) -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:102: diff -b -B \$abs_srcdir/expr-testsuite/test.5.func4.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5.func4.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5.func4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.func4.base stderr" "EXPRTest.at:102"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5.func4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.func4.base stderr
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:102"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5488,8 +5500,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_68
 #AT_START_69
-at_fn_group_banner 69 'EXPRTest.at:82' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass)" ""
+at_fn_group_banner 69 'EXPRTest.at:104' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5506,28 +5518,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:104: \$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:104"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.a -k "" -b -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:104: 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:104"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:104"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5538,8 +5550,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_69
 #AT_START_70
-at_fn_group_banner 70 'EXPRTest.at:82' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass)" ""
+at_fn_group_banner 70 'EXPRTest.at:104' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5556,28 +5568,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:104: \$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:104"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.a -k "" -b -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:104: 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:104"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:104"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5588,8 +5600,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_70
 #AT_START_71
-at_fn_group_banner 71 'EXPRTest.at:83' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass)" ""
+at_fn_group_banner 71 'EXPRTest.at:105' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5606,28 +5618,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:105: \$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:105"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:105: 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:105"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:105"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5638,8 +5650,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_71
 #AT_START_72
-at_fn_group_banner 72 'EXPRTest.at:83' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass)" ""
+at_fn_group_banner 72 'EXPRTest.at:105' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5656,28 +5668,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:105: \$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:105"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:105: 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:105"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:105"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5688,8 +5700,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_72
 #AT_START_73
-at_fn_group_banner 73 'EXPRTest.at:84' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass)" ""
+at_fn_group_banner 73 'EXPRTest.at:106' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5706,28 +5718,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:106: \$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:106"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:106: 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:106"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:106"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5738,8 +5750,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_73
 #AT_START_74
-at_fn_group_banner 74 'EXPRTest.at:84' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass)" ""
+at_fn_group_banner 74 'EXPRTest.at:106' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5756,28 +5768,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:106: \$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:106"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:106: 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:106"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:106"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5788,8 +5800,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_74
 #AT_START_75
-at_fn_group_banner 75 'EXPRTest.at:85' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass)" ""
+at_fn_group_banner 75 'EXPRTest.at:107' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5806,28 +5818,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:107: \$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:107"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:107: 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:107"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:107"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5838,8 +5850,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_75
 #AT_START_76
-at_fn_group_banner 76 'EXPRTest.at:85' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass)" ""
+at_fn_group_banner 76 'EXPRTest.at:107' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5856,28 +5868,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:107: \$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:107"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:107: 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:107"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:107"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5888,8 +5900,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_76
 #AT_START_77
-at_fn_group_banner 77 'EXPRTest.at:86' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass)" ""
+at_fn_group_banner 77 'EXPRTest.at:108' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5906,28 +5918,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:108: \$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:108"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k "" -b -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:108: 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:108"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:108"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5938,8 +5950,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_77
 #AT_START_78
-at_fn_group_banner 78 'EXPRTest.at:86' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass)" ""
+at_fn_group_banner 78 'EXPRTest.at:108' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -5956,28 +5968,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:108: \$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:108"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k "" -b -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:108: 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:108"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:108"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -5988,8 +6000,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_78
 #AT_START_79
-at_fn_group_banner 79 'EXPRTest.at:87' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass)" ""
+at_fn_group_banner 79 'EXPRTest.at:109' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6006,28 +6018,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:109: \$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:109"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:109: 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:109"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:109"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6038,8 +6050,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_79
 #AT_START_80
-at_fn_group_banner 80 'EXPRTest.at:87' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass)" ""
+at_fn_group_banner 80 'EXPRTest.at:109' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6056,28 +6068,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:109: \$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:109"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:109: 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:109"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:109"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6088,8 +6100,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_80
 #AT_START_81
-at_fn_group_banner 81 'EXPRTest.at:88' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass)" ""
+at_fn_group_banner 81 'EXPRTest.at:110' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6106,28 +6118,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:110: \$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:110"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:110: 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:110"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:110"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6138,8 +6150,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_81
 #AT_START_82
-at_fn_group_banner 82 'EXPRTest.at:88' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass)" ""
+at_fn_group_banner 82 'EXPRTest.at:110' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6156,28 +6168,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:110: \$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:110"
+( $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" 5>&-
 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_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: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
+$as_echo "$at_srcdir/EXPRTest.at:110: 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:110"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:110"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6188,8 +6200,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_82
 #AT_START_83
-at_fn_group_banner 83 'EXPRTest.at:89' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass)" ""
+at_fn_group_banner 83 'EXPRTest.at:111' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6206,28 +6218,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:111: \$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:111"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:111"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:111: 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:111"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:111"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6238,8 +6250,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_83
 #AT_START_84
-at_fn_group_banner 84 'EXPRTest.at:89' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass)" ""
+at_fn_group_banner 84 'EXPRTest.at:111' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6256,28 +6268,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:111: \$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:111"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:111"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:111: 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:111"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:111"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6288,8 +6300,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_84
 #AT_START_85
-at_fn_group_banner 85 'EXPRTest.at:90' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass)" ""
+at_fn_group_banner 85 'EXPRTest.at:112' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6306,28 +6318,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:112: \$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:112"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:112"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:112: 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:112"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:112"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6338,8 +6350,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_85
 #AT_START_86
-at_fn_group_banner 86 'EXPRTest.at:90' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass)" ""
+at_fn_group_banner 86 'EXPRTest.at:112' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6356,28 +6368,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:112: \$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:112"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:112"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:112: 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:112"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:112"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6388,8 +6400,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_86
 #AT_START_87
-at_fn_group_banner 87 'EXPRTest.at:91' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass)" ""
+at_fn_group_banner 87 'EXPRTest.at:113' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6406,28 +6418,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:113: \$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:113"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:113"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:113: 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:113"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:113"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6438,8 +6450,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_87
 #AT_START_88
-at_fn_group_banner 88 'EXPRTest.at:91' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass)" ""
+at_fn_group_banner 88 'EXPRTest.at:113' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6456,28 +6468,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:113: \$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:113"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:113"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:113: 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:113"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:113"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6488,8 +6500,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_88
 #AT_START_89
-at_fn_group_banner 89 'EXPRTest.at:92' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass)" ""
+at_fn_group_banner 89 'EXPRTest.at:114' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6506,28 +6518,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:114: \$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:114"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k "" -b -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:114"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:114: 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:114"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:114"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6538,8 +6550,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_89
 #AT_START_90
-at_fn_group_banner 90 'EXPRTest.at:92' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass)" ""
+at_fn_group_banner 90 'EXPRTest.at:114' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6556,28 +6568,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:114: \$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:114"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k "" -b -f "dummy" || true
 ) >>"$at_stdout" 2>>"$at_stderr" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:114"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:114: 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:114"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:114"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6588,8 +6600,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_90
 #AT_START_91
-at_fn_group_banner 91 'EXPRTest.at:93' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass)" ""
+at_fn_group_banner 91 'EXPRTest.at:115' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6606,28 +6618,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:115: \$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:115"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:115"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:115: 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:115"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:115"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6638,8 +6650,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_91
 #AT_START_92
-at_fn_group_banner 92 'EXPRTest.at:93' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass)" ""
+at_fn_group_banner 92 'EXPRTest.at:115' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6656,28 +6668,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:115: \$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:115"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:115"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:115: 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:115"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:115"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6688,8 +6700,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_92
 #AT_START_93
-at_fn_group_banner 93 'EXPRTest.at:94' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass)" ""
+at_fn_group_banner 93 'EXPRTest.at:116' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6706,28 +6718,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:116: \$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:116"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:116"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:116: 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:116"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:116"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6738,8 +6750,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_93
 #AT_START_94
-at_fn_group_banner 94 'EXPRTest.at:94' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass)" ""
+at_fn_group_banner 94 'EXPRTest.at:116' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6756,28 +6768,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:116: \$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:116"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:116"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:116: 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:116"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:116"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6788,8 +6800,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_94
 #AT_START_95
-at_fn_group_banner 95 'EXPRTest.at:95' \
-  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass)" ""
+at_fn_group_banner 95 'EXPRTest.at:117' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6806,28 +6818,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:117: \$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:117"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:117"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:117: 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:117"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:117"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6838,8 +6850,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_95
 #AT_START_96
-at_fn_group_banner 96 'EXPRTest.at:95' \
-  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass)" ""
+at_fn_group_banner 96 'EXPRTest.at:117' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6856,28 +6868,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:117: \$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:117"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:117"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:117: 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:117"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:117"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6888,8 +6900,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_96
 #AT_START_97
-at_fn_group_banner 97 'EXPRTest.at:97' \
-  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k i (pass)" ""
+at_fn_group_banner 97 'EXPRTest.at:118' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6906,28 +6918,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:118: \$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:118"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:118"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:118: 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:118"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:118"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6938,8 +6950,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_97
 #AT_START_98
-at_fn_group_banner 98 'EXPRTest.at:97' \
-  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k i (pass)" ""
+at_fn_group_banner 98 'EXPRTest.at:118' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -6956,28 +6968,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:118: \$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:118"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:118"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:118: 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:118"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:118"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -6988,8 +7000,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_98
 #AT_START_99
-at_fn_group_banner 99 'EXPRTest.at:98' \
-  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass)" ""
+at_fn_group_banner 99 'EXPRTest.at:119' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -7006,28 +7018,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:119: \$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:119"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:119"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:119: 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:119"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:119"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -7038,8 +7050,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_99
 #AT_START_100
-at_fn_group_banner 100 'EXPRTest.at:98' \
-  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass)" ""
+at_fn_group_banner 100 'EXPRTest.at:119' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -7056,28 +7068,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:119: \$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:119"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:119"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:119: 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:119"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:119"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -7088,8 +7100,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_100
 #AT_START_101
-at_fn_group_banner 101 'EXPRTest.at:99' \
-  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass)" ""
+at_fn_group_banner 101 'EXPRTest.at:120' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -7106,28 +7118,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:120: \$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:120"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:120"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:120: 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:120"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:120"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -7138,8 +7150,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_101
 #AT_START_102
-at_fn_group_banner 102 'EXPRTest.at:99' \
-  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass)" ""
+at_fn_group_banner 102 'EXPRTest.at:120' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -7156,28 +7168,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:120: \$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:120"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:120"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:120: 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:120"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:120"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -7188,8 +7200,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_102
 #AT_START_103
-at_fn_group_banner 103 'EXPRTest.at:100' \
-  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass)" ""
+at_fn_group_banner 103 'EXPRTest.at:121' \
+  "expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -7206,28 +7218,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:121: \$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:121"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:121"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:121: 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:121"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:121"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -7238,8 +7250,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_103
 #AT_START_104
-at_fn_group_banner 104 'EXPRTest.at:100' \
-  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass)" ""
+at_fn_group_banner 104 'EXPRTest.at:121' \
+  "expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -7256,28 +7268,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:121: \$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:121"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:121"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:121: 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:121"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:121"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -7288,8 +7300,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_104
 #AT_START_105
-at_fn_group_banner 105 'EXPRTest.at:102' \
-  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass)" ""
+at_fn_group_banner 105 'EXPRTest.at:123' \
+  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k i (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -7306,28 +7318,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:123: \$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:123"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:123"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:123: 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:123"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:123"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -7338,8 +7350,8 @@ $at_traceon; }
 read at_status <"$at_status_file"
 #AT_STOP_105
 #AT_START_106
-at_fn_group_banner 106 'EXPRTest.at:102' \
-  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass)" ""
+at_fn_group_banner 106 'EXPRTest.at:123' \
+  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k i (pass)" ""
 at_xfail=no
       test "pass" = "xfail" && at_xfail=yes
 (
@@ -7356,28 +7368,28 @@ at_xfail=no
     # 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
+$as_echo "$at_srcdir/EXPRTest.at:123: \$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:123"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:123"
 $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
+$as_echo "$at_srcdir/EXPRTest.at:123: 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:123"
+( $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" 5>&-
 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_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:123"
 $at_failed && at_fn_log_failure
 $at_traceon; }
 
@@ -7387,3 +7399,603 @@ $at_traceon; }
 ) 5>&1 2>&1 7>&- | eval $at_tee_pipe
 read at_status <"$at_status_file"
 #AT_STOP_106
+#AT_START_107
+at_fn_group_banner 107 'EXPRTest.at:124' \
+  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "107. $at_setup_line: testing $at_desc ..."
+  $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:124: \$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:124"
+( $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" 5>&-
+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:124"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:124: 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:124"
+( $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" 5>&-
+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:124"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_107
+#AT_START_108
+at_fn_group_banner 108 'EXPRTest.at:124' \
+  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "108. $at_setup_line: testing $at_desc ..."
+  $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:124: \$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:124"
+( $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" 5>&-
+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:124"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:124: 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:124"
+( $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" 5>&-
+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:124"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_108
+#AT_START_109
+at_fn_group_banner 109 'EXPRTest.at:125' \
+  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "109. $at_setup_line: testing $at_desc ..."
+  $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:125: \$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:125"
+( $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" 5>&-
+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:125"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:125: 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:125"
+( $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" 5>&-
+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:125"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_109
+#AT_START_110
+at_fn_group_banner 110 'EXPRTest.at:125' \
+  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "110. $at_setup_line: testing $at_desc ..."
+  $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:125: \$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:125"
+( $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" 5>&-
+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:125"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:125: 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:125"
+( $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" 5>&-
+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:125"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_110
+#AT_START_111
+at_fn_group_banner 111 'EXPRTest.at:126' \
+  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "111. $at_setup_line: testing $at_desc ..."
+  $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:126: \$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:126"
+( $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" 5>&-
+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:126"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:126: 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:126"
+( $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" 5>&-
+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:126"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_111
+#AT_START_112
+at_fn_group_banner 112 'EXPRTest.at:126' \
+  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "112. $at_setup_line: testing $at_desc ..."
+  $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:126: \$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:126"
+( $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" 5>&-
+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:126"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:126: 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:126"
+( $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" 5>&-
+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:126"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_112
+#AT_START_113
+at_fn_group_banner 113 'EXPRTest.at:127' \
+  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "113. $at_setup_line: testing $at_desc ..."
+  $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:127: \$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:127"
+( $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" 5>&-
+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:127"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:127: 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:127"
+( $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" 5>&-
+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:127"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_113
+#AT_START_114
+at_fn_group_banner 114 'EXPRTest.at:127' \
+  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "114. $at_setup_line: testing $at_desc ..."
+  $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:127: \$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:127"
+( $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" 5>&-
+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:127"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:127: 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:127"
+( $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" 5>&-
+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:127"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_114
+#AT_START_115
+at_fn_group_banner 115 'EXPRTest.at:129' \
+  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.f -k \"\" (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "115. $at_setup_line: testing $at_desc ..."
+  $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:129: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.f -k \"\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.f -k \"\" -f \"dummy\" || true" "EXPRTest.at:129"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.f -k "" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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:129"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:129: diff -b -B \$abs_srcdir/expr-testsuite/test.fa.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.fa.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.fa.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.fa.base stderr" "EXPRTest.at:129"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.fa.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.fa.base stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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:129"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_115
+#AT_START_116
+at_fn_group_banner 116 'EXPRTest.at:129' \
+  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.f -k \"\" (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "116. $at_setup_line: testing $at_desc ..."
+  $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:129: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.f -k \"\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.f -k \"\" -f \"dummy\" || true" "EXPRTest.at:129"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.f -k "" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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:129"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:129: diff -b -B \$abs_srcdir/expr-testsuite/test.fa.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.fa.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.fa.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.fa.base stderr" "EXPRTest.at:129"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.fa.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.fa.base stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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:129"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_116
+#AT_START_117
+at_fn_group_banner 117 'EXPRTest.at:130' \
+  "expr-test -b -w \$abs_srcdir/expr-testsuite/test.f -k \"&i<3000\" (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "117. $at_setup_line: testing $at_desc ..."
+  $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:130: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.f -k \"&i<3000\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.f -k \"&i<3000\" -f \"dummy\" || true" "EXPRTest.at:130"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.f -k "&i<3000" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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:130"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:130: diff -b -B \$abs_srcdir/expr-testsuite/test.fb.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.fb.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.fb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.fb.base stderr" "EXPRTest.at:130"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.fb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.fb.base stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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:130"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_117
+#AT_START_118
+at_fn_group_banner 118 'EXPRTest.at:130' \
+  "expr-test -b -W \$abs_srcdir/expr-testsuite/test.f -k \"&i<3000\" (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "118. $at_setup_line: testing $at_desc ..."
+  $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:130: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.f -k \"&i<3000\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.f -k \"&i<3000\" -f \"dummy\" || true" "EXPRTest.at:130"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.f -k "&i<3000" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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:130"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:130: diff -b -B \$abs_srcdir/expr-testsuite/test.fb.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.fb.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.fb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.fb.base stderr" "EXPRTest.at:130"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.fb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.fb.base stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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:130"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_118
diff --git a/tests/EXPRTest.at b/tests/EXPRTest.at
index f585e57..c5264b2 100644
--- a/tests/EXPRTest.at
+++ b/tests/EXPRTest.at
@@ -58,8 +58,24 @@ EXPR_RESPONSE_P([test.2a], [s2[[2:4]].m[[0:4]],s2[[2:4]].l[[0:5]]], [test.2f], [
 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])
+dnl In changing the TestStr class so that it writes a constant value (Silly ...: 1)
+dnl I had to hack this test to use the -b option to expr-test. EXPR_RESPONSE_P uses
+dnl only the -w/-W options, so I dropped using that macro kluge and went right for the
+dnl actual test macro. 12/2/13/ jhrg
+dnl
+dnl EXPR_RESPONSE_P([test.e], ['names.s&names.s=~".*: 3"'], [test.ea], [pass])
+    
+_EXPR_TEST([-b -w], [$abs_srcdir/expr-testsuite/test.e], ['names.s&names.s=~".*: 3"'], 
+    [$abs_srcdir/expr-testsuite/test.ea.base], [pass])
+    
+_EXPR_TEST([-b -W], [$abs_srcdir/expr-testsuite/test.e], ['names.s&names.s=~".*: 3"'], 
+    [$abs_srcdir/expr-testsuite/test.ea.base], [pass])
+
+dnl since 'Silly ...:5' will never be produced, this tests what happens when the sequence
+dnl does not contain the value. Note that this test does not have to be rewritten because
+dnl of the change to the TestStr code. 12/2/13 jhrg
 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])
@@ -75,6 +91,16 @@ 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])
+
+# New tests for server functions that take arrays and include array projections
+# Added 10/23/13 jhrg
+EXPR_RESPONSE_P([test.6], [scale\(i,2\)], [test.6.func1], [pass])
+EXPR_RESPONSE_P([test.6], [scale\(i[[2:4]][[3:6]],2\)], [test.6.func2], [pass])
+
+EXPR_RESPONSE_P([test.5], [scale\(i[[3]],2\)], [test.5.func3], [pass])
+# This doesn't work yet 10/23/13 jhrg 
+EXPR_RESPONSE_P([test.5], [scale\(j,2\)], [test.5.func4], [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])
@@ -98,27 +124,7 @@ 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])
+EXPR_RESPONSE_B([test.f], [""], [test.fa], [pass])
+EXPR_RESPONSE_B([test.f], ["&i<3000"], [test.fb], [pass])
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 70a270b..0b76411 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -3,38 +3,41 @@
 AUTOMAKE_OPTIONS = foreign
 
 # Arrange to build with the backward compatibility mode enabled.
-AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/GNU $(XML2_CFLAGS) $(CURL_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/GNU -I$(top_srcdir)/d4_ce $(XML2_CFLAGS) $(CURL_CFLAGS)
 AM_CXXFLAGS =  
 
 if COMPILER_IS_GCC
 AM_CXXFLAGS += -Wall -W -Wcast-align
 endif
 
-# These are not used by automake but are often useful for certain types of
-# debugging. 
 CXXFLAGS_DEBUG = -g3 -O0  -Wall -W -Wcast-align
 TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
 
+if BUILD_DEVELOPER
+AM_CXXFLAGS += $(CXXFLAGS_DEBUG)
+endif
+
 check_PROGRAMS = das-test dds-test expr-test 
 
-TESTS = DASTest DDSTest EXPRTest
+if DAP4_DEFINED
+check_PROGRAMS += dmr-test
+endif
 
-dist_check_SCRIPTS = DASTest DDSTest EXPRTest atconfig atlocal
+TESTS = DASTest DDSTest EXPRTest DMRTest getdapTest
+
+dist_check_SCRIPTS = DASTest DDSTest EXPRTest DMRTest getdapTest atconfig atlocal
 
 # Build the test drivers. The drivers all use the
 # subclassed types in Test*.cc and the TestTypesFactory.
 
-#noinst_LIBRARIES = libtest-types.a
 lib_LIBRARIES = libtest-types.a
 
 libtest_types_a_SOURCES = $(TESTSRCS) $(TEST_HDR)
+libtest_types_a_CXXFLAGS = -fPIC
 
 testheadersdir = $(pkgincludedir)/test
 testheaders_HEADERS = $(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 
 
@@ -44,50 +47,73 @@ dds_test_LDADD = libtest-types.a ../libdapserver.la ../libdap.la
 expr_test_SOURCES = expr-test.cc ResponseBuilder.cc ResponseBuilder.h
 expr_test_LDADD = libtest-types.a ../libdapserver.la ../libdapclient.la ../libdap.la
 
+if DAP4_DEFINED
+dmr_test_SOURCES = dmr-test.cc D4ResponseBuilder.cc D4ResponseBuilder.h
+dmr_test_LDADD = libtest-types.a ../libdapserver.la ../libdap.la
+endif
+
 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
+	   TestFloat32.cc TestTypeFactory.cc D4TestTypeFactory.cc \
+	   TestD4Group.cc TestInt8.cc TestInt64.cc TestUInt64.cc TestD4Sequence.cc \
+	   TestD4Enum.cc TestD4Opaque.cc TestFunction.cc D4TestFunction.cc
+
+# TestCommon.cc Removed jhrg 3/12/15
 
 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
+	TestStructure.h TestTypeFactory.h TestUInt16.h TestUInt32.h TestUrl.h \
+	D4TestTypeFactory.h TestD4Group.h TestInt8.h TestInt64.h TestUInt64.h \
+	TestD4Sequence.h TestD4Enum.h TestD4Opaque.h TestFunction.h D4TestFunction.h
+
+DIRS_EXTRA = das-testsuite dds-testsuite expr-testsuite dmr-testsuite \
+	getdap-testsuite
+
+EXTRA_DIST = DASTest.at  $(DASTESTSUITE) DDSTest.at $(DDSTESTSUITE) \
+	EXPRTest.at $(EXPRTESTSUITE) DMRTest.at $(DMRTESTSUITE) \
+	 getdapTest.at getdap-testsuite atlocal.in $(srcdir)/package.m4 $(DIRS_EXTRA)
 
-DIRS_EXTRA = das-testsuite dds-testsuite expr-testsuite 
+CLEANFILES = dmr-testsuite.tar.gz
 
-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/* DMRTest.dir/* \
+	getdapTest.dir/*
 
-DISTCLEANFILES = *.log DASTest.dir/* DDSTest.dir/* EXPRTest.dir/*
+dmr-testsuite.tar.gz: dmr-testsuite/*.xml
+	tar -czf $@ $^
 
 ############## Autotest follows #####################
 
 AUTOM4TE = autom4te
 
-DASTESTSUITE = $(srcdir)/DASTest 
+DASTESTSUITE = $(srcdir)/DASTest
 DASTESTSUITEFLAGS =
-DDSTESTSUITE = $(srcdir)/DDSTest 
+
+DDSTESTSUITE = $(srcdir)/DDSTest
 DDSTESTSUITEFLAGS =
-EXPRTESTSUITE = $(srcdir)/EXPRTest 
-EXPRTESTSUITEFLAGS =
 
-#check-local: check-das check-dds
+EXPRTESTSUITE = $(srcdir)/EXPRTest
+EXPRTESTSUITEFLAGS =
 
-#check-das: atconfig atlocal $(DASTESTSUITE)
-#	$(SHELL) $(DASTESTSUITE) $(DASTESTSUITEFLAGS)
+DMRTESTSUITE = $(srcdir)/DMRTest
+DMRTESTSUITEFLAGS =
 
-#check-dds: atconfig atlocal $(DDSTESTSUITE)
-#	$(SHELL) $(DDSTESTSUITE) $(DDSTESTSUITEFLAGS)
+GETDAPTESTSUITE = $(srcdir)/getdapTest
+GETDAPTESTSUITEFLAGS =
 
+# Make sure there are no spaces after the DASTESTSUITE names. jhrg 3/16/15
 clean-local:
 	test ! -f '$(DASTESTSUITE)' || $(SHELL) $(DASTESTSUITE) --clean
 	test ! -f '$(DDSTESTSUITE)' || $(SHELL) $(DDSTESTSUITE) --clean
+	test ! -f '$(EXPRTESTSUITE)' || $(SHELL) $(EXPRTESTSUITE) --clean
+	test ! -f '$(DMRTESTSUITE)' || $(SHELL) $(DMRTESTSUITE) --clean
+	test ! -f '$(GETDAPTESTSUITE)' || $(SHELL) $(GETDAPTESTSUITE) --clean
 
 distclean-local:
 	-rm atconfig
 
 AUTOTEST = $(AUTOM4TE) --language=autotest
+
 $(DASTESTSUITE): $(srcdir)/DASTest.at $(srcdir)/package.m4
 	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
 	mv $@.tmp $@
@@ -100,6 +126,14 @@ $(EXPRTESTSUITE): $(srcdir)/EXPRTest.at $(srcdir)/package.m4
 	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
 	mv $@.tmp $@
 
+$(DMRTESTSUITE): $(srcdir)/DMRTest.at $(srcdir)/package.m4
+	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+	mv $@.tmp $@
+
+$(GETDAPTESTSUITE): $(srcdir)/getdapTest.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
 	:;{ \
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 5c027c8..02dc972 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -54,8 +54,10 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 @COMPILER_IS_GCC_TRUE at am__append_1 = -Wall -W -Wcast-align
+ at BUILD_DEVELOPER_TRUE@am__append_2 = $(CXXFLAGS_DEBUG)
 check_PROGRAMS = das-test$(EXEEXT) dds-test$(EXEEXT) \
-	expr-test$(EXEEXT)
+	expr-test$(EXEEXT) $(am__EXEEXT_1)
+ at DAP4_DEFINED_TRUE@am__append_3 = dmr-test
 subdir = tests
 DIST_COMMON = README $(dist_check_SCRIPTS) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/atlocal.in \
@@ -65,19 +67,23 @@ 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/byteswap.m4 $(top_srcdir)/gl/m4/codeset.m4 \
 	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/eealloc.m4 \
 	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/extern-inline.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/lib-ld.m4 $(top_srcdir)/gl/m4/lib-link.m4 \
+	$(top_srcdir)/gl/m4/lib-prefix.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/locale_h.m4 \
-	$(top_srcdir)/gl/m4/localeconv.m4 \
+	$(top_srcdir)/gl/m4/localeconv.m4 $(top_srcdir)/gl/m4/lock.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/mbtowc.m4 \
@@ -86,17 +92,18 @@ am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
 	$(top_srcdir)/gl/m4/off_t.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/strcase.m4 \
-	$(top_srcdir)/gl/m4/strings_h.m4 \
+	$(top_srcdir)/gl/m4/stdlib_h.m4 \
 	$(top_srcdir)/gl/m4/sys_types_h.m4 \
+	$(top_srcdir)/gl/m4/threadlib.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/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/cppunit.m4 \
+	$(top_srcdir)/conf/gcov_valgrind.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) \
@@ -138,15 +145,34 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(testheadersdir)"
 LIBRARIES = $(lib_LIBRARIES)
 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_1 = libtest_types_a-TestByte.$(OBJEXT) \
+	libtest_types_a-TestInt32.$(OBJEXT) \
+	libtest_types_a-TestFloat64.$(OBJEXT) \
+	libtest_types_a-TestStr.$(OBJEXT) \
+	libtest_types_a-TestUrl.$(OBJEXT) \
+	libtest_types_a-TestArray.$(OBJEXT) \
+	libtest_types_a-TestStructure.$(OBJEXT) \
+	libtest_types_a-TestSequence.$(OBJEXT) \
+	libtest_types_a-TestGrid.$(OBJEXT) \
+	libtest_types_a-TestUInt32.$(OBJEXT) \
+	libtest_types_a-TestInt16.$(OBJEXT) \
+	libtest_types_a-TestUInt16.$(OBJEXT) \
+	libtest_types_a-TestFloat32.$(OBJEXT) \
+	libtest_types_a-TestTypeFactory.$(OBJEXT) \
+	libtest_types_a-D4TestTypeFactory.$(OBJEXT) \
+	libtest_types_a-TestD4Group.$(OBJEXT) \
+	libtest_types_a-TestInt8.$(OBJEXT) \
+	libtest_types_a-TestInt64.$(OBJEXT) \
+	libtest_types_a-TestUInt64.$(OBJEXT) \
+	libtest_types_a-TestD4Sequence.$(OBJEXT) \
+	libtest_types_a-TestD4Enum.$(OBJEXT) \
+	libtest_types_a-TestD4Opaque.$(OBJEXT) \
+	libtest_types_a-TestFunction.$(OBJEXT) \
+	libtest_types_a-D4TestFunction.$(OBJEXT)
 am__objects_2 =
 am_libtest_types_a_OBJECTS = $(am__objects_1) $(am__objects_2)
 libtest_types_a_OBJECTS = $(am_libtest_types_a_OBJECTS)
+ at DAP4_DEFINED_TRUE@am__EXEEXT_1 = dmr-test$(EXEEXT)
 am_das_test_OBJECTS = das-test.$(OBJEXT)
 das_test_OBJECTS = $(am_das_test_OBJECTS)
 das_test_DEPENDENCIES = libtest-types.a ../libdapserver.la \
@@ -155,6 +181,13 @@ 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__dmr_test_SOURCES_DIST = dmr-test.cc D4ResponseBuilder.cc \
+	D4ResponseBuilder.h
+ at DAP4_DEFINED_TRUE@am_dmr_test_OBJECTS = dmr-test.$(OBJEXT) \
+ at DAP4_DEFINED_TRUE@	D4ResponseBuilder.$(OBJEXT)
+dmr_test_OBJECTS = $(am_dmr_test_OBJECTS)
+ at DAP4_DEFINED_TRUE@dmr_test_DEPENDENCIES = libtest-types.a \
+ at DAP4_DEFINED_TRUE@	../libdapserver.la ../libdap.la
 am_expr_test_OBJECTS = expr-test.$(OBJEXT) ResponseBuilder.$(OBJEXT)
 expr_test_OBJECTS = $(am_expr_test_OBJECTS)
 expr_test_DEPENDENCIES = libtest-types.a ../libdapserver.la \
@@ -182,9 +215,10 @@ 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)
+	$(dds_test_SOURCES) $(dmr_test_SOURCES) $(expr_test_SOURCES)
 DIST_SOURCES = $(libtest_types_a_SOURCES) $(das_test_SOURCES) \
-	$(dds_test_SOURCES) $(expr_test_SOURCES)
+	$(dds_test_SOURCES) $(am__dmr_test_SOURCES_DIST) \
+	$(expr_test_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -250,7 +284,6 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
-EVAL = @EVAL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GLIBC21 = @GLIBC21@
@@ -271,7 +304,6 @@ GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
 GNULIB_FCHDIR = @GNULIB_FCHDIR@
 GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
 GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
-GNULIB_FFS = @GNULIB_FFS@
 GNULIB_FSYNC = @GNULIB_FSYNC@
 GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
 GNULIB_GETCWD = @GNULIB_GETCWD@
@@ -325,6 +357,7 @@ GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
 GNULIB_REALPATH = @GNULIB_REALPATH@
 GNULIB_RMDIR = @GNULIB_RMDIR@
 GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
 GNULIB_SETENV = @GNULIB_SETENV@
 GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
 GNULIB_SETLOCALE = @GNULIB_SETLOCALE@
@@ -397,7 +430,6 @@ HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
 HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
 HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
 HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
-HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
 HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
 HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
 HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
@@ -411,7 +443,6 @@ HAVE_FCHDIR = @HAVE_FCHDIR@
 HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
 HAVE_FDATASYNC = @HAVE_FDATASYNC@
 HAVE_FEATURES_H = @HAVE_FEATURES_H@
-HAVE_FFS = @HAVE_FFS@
 HAVE_FSYNC = @HAVE_FSYNC@
 HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
 HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
@@ -460,6 +491,7 @@ HAVE_READLINK = @HAVE_READLINK@
 HAVE_READLINKAT = @HAVE_READLINKAT@
 HAVE_REALPATH = @HAVE_REALPATH@
 HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
 HAVE_SETENV = @HAVE_SETENV@
 HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
 HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
@@ -467,8 +499,6 @@ 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_STRCASECMP = @HAVE_STRCASECMP@
-HAVE_STRINGS_H = @HAVE_STRINGS_H@
 HAVE_STRTOD = @HAVE_STRTOD@
 HAVE_STRTOLL = @HAVE_STRTOLL@
 HAVE_STRTOULL = @HAVE_STRTOULL@
@@ -485,6 +515,7 @@ HAVE_UNLINKAT = @HAVE_UNLINKAT@
 HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
 HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
 HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_VALGRIND = @HAVE_VALGRIND@
 HAVE_WCHAR_H = @HAVE_WCHAR_H@
 HAVE_WCHAR_T = @HAVE_WCHAR_T@
 HAVE_WCPCPY = @HAVE_WCPCPY@
@@ -539,8 +570,12 @@ LEXLIB = @LEXLIB@
 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
 LIBDAP_VERSION = @LIBDAP_VERSION@
 LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
 LIBS = @LIBS@
+LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -550,7 +585,10 @@ LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
 LOCALE_JA = @LOCALE_JA@
 LOCALE_ZH_CN = @LOCALE_ZH_CN@
 LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -559,7 +597,6 @@ NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_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_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
 NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_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@
@@ -569,7 +606,6 @@ NEXT_LOCALE_H = @NEXT_LOCALE_H@
 NEXT_STDDEF_H = @NEXT_STDDEF_H@
 NEXT_STDINT_H = @NEXT_STDINT_H@
 NEXT_STDLIB_H = @NEXT_STDLIB_H@
-NEXT_STRINGS_H = @NEXT_STRINGS_H@
 NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
 NEXT_UNISTD_H = @NEXT_UNISTD_H@
 NEXT_WCHAR_H = @NEXT_WCHAR_H@
@@ -609,6 +645,7 @@ REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
 REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
 REPLACE_GETCWD = @REPLACE_GETCWD@
 REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
 REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
 REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
 REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
@@ -632,6 +669,7 @@ REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
 REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
 REPLACE_NULL = @REPLACE_NULL@
 REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
 REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
 REPLACE_PUTENV = @REPLACE_PUTENV@
 REPLACE_PWRITE = @REPLACE_PWRITE@
@@ -737,6 +775,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -750,57 +789,67 @@ xmlprivatereq = @xmlprivatereq@
 AUTOMAKE_OPTIONS = foreign
 
 # Arrange to build with the backward compatibility mode enabled.
-AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/GNU $(XML2_CFLAGS) $(CURL_CFLAGS)
-AM_CXXFLAGS = $(am__append_1)
-
-# These are not used by automake but are often useful for certain types of
-# debugging. 
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/GNU -I$(top_srcdir)/d4_ce $(XML2_CFLAGS) $(CURL_CFLAGS)
+AM_CXXFLAGS = $(am__append_1) $(am__append_2)
 CXXFLAGS_DEBUG = -g3 -O0  -Wall -W -Wcast-align
 TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
-TESTS = DASTest DDSTest EXPRTest
-dist_check_SCRIPTS = DASTest DDSTest EXPRTest atconfig atlocal
+TESTS = DASTest DDSTest EXPRTest DMRTest getdapTest
+dist_check_SCRIPTS = DASTest DDSTest EXPRTest DMRTest getdapTest atconfig atlocal
 
 # Build the test drivers. The drivers all use the
 # subclassed types in Test*.cc and the TestTypesFactory.
-
-#noinst_LIBRARIES = libtest-types.a
 lib_LIBRARIES = libtest-types.a
 libtest_types_a_SOURCES = $(TESTSRCS) $(TEST_HDR)
+libtest_types_a_CXXFLAGS = -fPIC
 testheadersdir = $(pkgincludedir)/test
 testheaders_HEADERS = $(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 ResponseBuilder.cc ResponseBuilder.h
 expr_test_LDADD = libtest-types.a ../libdapserver.la ../libdapclient.la ../libdap.la
+ at DAP4_DEFINED_TRUE@dmr_test_SOURCES = dmr-test.cc D4ResponseBuilder.cc D4ResponseBuilder.h
+ at DAP4_DEFINED_TRUE@dmr_test_LDADD = libtest-types.a ../libdapserver.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
+	   TestFloat32.cc TestTypeFactory.cc D4TestTypeFactory.cc \
+	   TestD4Group.cc TestInt8.cc TestInt64.cc TestUInt64.cc TestD4Sequence.cc \
+	   TestD4Enum.cc TestD4Opaque.cc TestFunction.cc D4TestFunction.cc
+
 
+# TestCommon.cc Removed jhrg 3/12/15
 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
+	TestStructure.h TestTypeFactory.h TestUInt16.h TestUInt32.h TestUrl.h \
+	D4TestTypeFactory.h TestD4Group.h TestInt8.h TestInt64.h TestUInt64.h \
+	TestD4Sequence.h TestD4Enum.h TestD4Opaque.h TestFunction.h D4TestFunction.h
 
-DIRS_EXTRA = das-testsuite dds-testsuite expr-testsuite 
-EXTRA_DIST = DASTest.at  $(DASTESTSUITE) DDSTest.at  $(DDSTESTSUITE) \
-	EXPRTest.at $(EXPRTESTSUITE) atlocal.in $(srcdir)/package.m4 \
-	$(DIRS_EXTRA)
+DIRS_EXTRA = das-testsuite dds-testsuite expr-testsuite dmr-testsuite \
+	getdap-testsuite
+
+EXTRA_DIST = DASTest.at  $(DASTESTSUITE) DDSTest.at $(DDSTESTSUITE) \
+	EXPRTest.at $(EXPRTESTSUITE) DMRTest.at $(DMRTESTSUITE) \
+	 getdapTest.at getdap-testsuite atlocal.in $(srcdir)/package.m4 $(DIRS_EXTRA)
+
+CLEANFILES = dmr-testsuite.tar.gz
+DISTCLEANFILES = *.log DASTest.dir/* DDSTest.dir/* EXPRTest.dir/* DMRTest.dir/* \
+	getdapTest.dir/*
 
-DISTCLEANFILES = *.log DASTest.dir/* DDSTest.dir/* EXPRTest.dir/*
 
 ############## Autotest follows #####################
 AUTOM4TE = autom4te
-DASTESTSUITE = $(srcdir)/DASTest 
+DASTESTSUITE = $(srcdir)/DASTest
 DASTESTSUITEFLAGS = 
-DDSTESTSUITE = $(srcdir)/DDSTest 
+DDSTESTSUITE = $(srcdir)/DDSTest
 DDSTESTSUITEFLAGS = 
-EXPRTESTSUITE = $(srcdir)/EXPRTest 
+EXPRTESTSUITE = $(srcdir)/EXPRTest
 EXPRTESTSUITEFLAGS = 
+DMRTESTSUITE = $(srcdir)/DMRTest
+DMRTESTSUITEFLAGS = 
+GETDAPTESTSUITE = $(srcdir)/getdapTest
+GETDAPTESTSUITEFLAGS = 
 AUTOTEST = $(AUTOM4TE) --language=autotest
 all: all-am
 
@@ -888,6 +937,9 @@ das-test$(EXEEXT): $(das_test_OBJECTS) $(das_test_DEPENDENCIES) $(EXTRA_das_test
 dds-test$(EXEEXT): $(dds_test_OBJECTS) $(dds_test_DEPENDENCIES) $(EXTRA_dds_test_DEPENDENCIES) 
 	@rm -f dds-test$(EXEEXT)
 	$(CXXLINK) $(dds_test_OBJECTS) $(dds_test_LDADD) $(LIBS)
+dmr-test$(EXEEXT): $(dmr_test_OBJECTS) $(dmr_test_DEPENDENCIES) $(EXTRA_dmr_test_DEPENDENCIES) 
+	@rm -f dmr-test$(EXEEXT)
+	$(CXXLINK) $(dmr_test_OBJECTS) $(dmr_test_LDADD) $(LIBS)
 expr-test$(EXEEXT): $(expr_test_OBJECTS) $(expr_test_DEPENDENCIES) $(EXTRA_expr_test_DEPENDENCIES) 
 	@rm -f expr-test$(EXEEXT)
 	$(CXXLINK) $(expr_test_OBJECTS) $(expr_test_LDADD) $(LIBS)
@@ -898,25 +950,36 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4ResponseBuilder.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ResponseBuilder.Po at am__quote@
- 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@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/das-test.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dds-test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dmr-test.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/expr-test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-D4TestFunction.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-D4TestTypeFactory.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestArray.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestByte.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestD4Enum.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestD4Group.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestD4Opaque.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestD4Sequence.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestFloat32.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestFloat64.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestFunction.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestGrid.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestInt16.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestInt32.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestInt64.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestInt8.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestSequence.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestStr.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestStructure.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestTypeFactory.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestUInt16.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestUInt32.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestUInt64.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libtest_types_a-TestUrl.Po at am__quote@
 
 .cc.o:
 @am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -939,6 +1002,342 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
 
+libtest_types_a-TestByte.o: TestByte.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestByte.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestByte.Tpo -c -o libtest_types_a-TestByte.o `test -f 'TestByte.cc' || echo '$(srcdir)/'`TestByte.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestByte.Tpo $(DEPDIR)/libtest_types_a-TestByte.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestByte.cc' object='libtest_types_a-TestByte.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestByte.o `test -f 'TestByte.cc' || echo '$(srcdir)/'`TestByte.cc
+
+libtest_types_a-TestByte.obj: TestByte.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestByte.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestByte.Tpo -c -o libtest_types_a-TestByte.obj `if test -f 'TestByte.cc'; then $(CYGPATH_W) 'TestByte.cc'; else $(CYGPATH_W) '$(srcdir)/TestByte.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestByte.Tpo $(DEPDIR)/libtest_types_a-TestByte.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestByte.cc' object='libtest_types_a-TestByte.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestByte.obj `if test -f 'TestByte.cc'; then $(CYGPATH_W) 'TestByte.cc'; else $(CYGPATH_W) '$(srcdir)/TestByte.cc'; fi`
+
+libtest_types_a-TestInt32.o: TestInt32.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestInt32.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestInt32.Tpo -c -o libtest_types_a-TestInt32.o `test -f 'TestInt32.cc' || echo '$(srcdir)/'`TestInt32.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestInt32.Tpo $(DEPDIR)/libtest_types_a-TestInt32.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestInt32.cc' object='libtest_types_a-TestInt32.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestInt32.o `test -f 'TestInt32.cc' || echo '$(srcdir)/'`TestInt32.cc
+
+libtest_types_a-TestInt32.obj: TestInt32.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestInt32.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestInt32.Tpo -c -o libtest_types_a-TestInt32.obj `if test -f 'TestInt32.cc'; then $(CYGPATH_W) 'TestInt32.cc'; else $(CYGPATH_W) '$(srcdir)/TestInt32.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestInt32.Tpo $(DEPDIR)/libtest_types_a-TestInt32.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestInt32.cc' object='libtest_types_a-TestInt32.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestInt32.obj `if test -f 'TestInt32.cc'; then $(CYGPATH_W) 'TestInt32.cc'; else $(CYGPATH_W) '$(srcdir)/TestInt32.cc'; fi`
+
+libtest_types_a-TestFloat64.o: TestFloat64.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestFloat64.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestFloat64.Tpo -c -o libtest_types_a-TestFloat64.o `test -f 'TestFloat64.cc' || echo '$(srcdir)/'`TestFloat64.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestFloat64.Tpo $(DEPDIR)/libtest_types_a-TestFloat64.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestFloat64.cc' object='libtest_types_a-TestFloat64.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestFloat64.o `test -f 'TestFloat64.cc' || echo '$(srcdir)/'`TestFloat64.cc
+
+libtest_types_a-TestFloat64.obj: TestFloat64.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestFloat64.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestFloat64.Tpo -c -o libtest_types_a-TestFloat64.obj `if test -f 'TestFloat64.cc'; then $(CYGPATH_W) 'TestFloat64.cc'; else $(CYGPATH_W) '$(srcdir)/TestFloat64.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestFloat64.Tpo $(DEPDIR)/libtest_types_a-TestFloat64.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestFloat64.cc' object='libtest_types_a-TestFloat64.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestFloat64.obj `if test -f 'TestFloat64.cc'; then $(CYGPATH_W) 'TestFloat64.cc'; else $(CYGPATH_W) '$(srcdir)/TestFloat64.cc'; fi`
+
+libtest_types_a-TestStr.o: TestStr.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestStr.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestStr.Tpo -c -o libtest_types_a-TestStr.o `test -f 'TestStr.cc' || echo '$(srcdir)/'`TestStr.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestStr.Tpo $(DEPDIR)/libtest_types_a-TestStr.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestStr.cc' object='libtest_types_a-TestStr.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestStr.o `test -f 'TestStr.cc' || echo '$(srcdir)/'`TestStr.cc
+
+libtest_types_a-TestStr.obj: TestStr.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestStr.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestStr.Tpo -c -o libtest_types_a-TestStr.obj `if test -f 'TestStr.cc'; then $(CYGPATH_W) 'TestStr.cc'; else $(CYGPATH_W) '$(srcdir)/TestStr.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestStr.Tpo $(DEPDIR)/libtest_types_a-TestStr.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestStr.cc' object='libtest_types_a-TestStr.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestStr.obj `if test -f 'TestStr.cc'; then $(CYGPATH_W) 'TestStr.cc'; else $(CYGPATH_W) '$(srcdir)/TestStr.cc'; fi`
+
+libtest_types_a-TestUrl.o: TestUrl.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestUrl.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestUrl.Tpo -c -o libtest_types_a-TestUrl.o `test -f 'TestUrl.cc' || echo '$(srcdir)/'`TestUrl.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestUrl.Tpo $(DEPDIR)/libtest_types_a-TestUrl.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestUrl.cc' object='libtest_types_a-TestUrl.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestUrl.o `test -f 'TestUrl.cc' || echo '$(srcdir)/'`TestUrl.cc
+
+libtest_types_a-TestUrl.obj: TestUrl.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestUrl.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestUrl.Tpo -c -o libtest_types_a-TestUrl.obj `if test -f 'TestUrl.cc'; then $(CYGPATH_W) 'TestUrl.cc'; else $(CYGPATH_W) '$(srcdir)/TestUrl.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestUrl.Tpo $(DEPDIR)/libtest_types_a-TestUrl.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestUrl.cc' object='libtest_types_a-TestUrl.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestUrl.obj `if test -f 'TestUrl.cc'; then $(CYGPATH_W) 'TestUrl.cc'; else $(CYGPATH_W) '$(srcdir)/TestUrl.cc'; fi`
+
+libtest_types_a-TestArray.o: TestArray.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestArray.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestArray.Tpo -c -o libtest_types_a-TestArray.o `test -f 'TestArray.cc' || echo '$(srcdir)/'`TestArray.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestArray.Tpo $(DEPDIR)/libtest_types_a-TestArray.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestArray.cc' object='libtest_types_a-TestArray.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestArray.o `test -f 'TestArray.cc' || echo '$(srcdir)/'`TestArray.cc
+
+libtest_types_a-TestArray.obj: TestArray.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestArray.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestArray.Tpo -c -o libtest_types_a-TestArray.obj `if test -f 'TestArray.cc'; then $(CYGPATH_W) 'TestArray.cc'; else $(CYGPATH_W) '$(srcdir)/TestArray.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestArray.Tpo $(DEPDIR)/libtest_types_a-TestArray.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestArray.cc' object='libtest_types_a-TestArray.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestArray.obj `if test -f 'TestArray.cc'; then $(CYGPATH_W) 'TestArray.cc'; else $(CYGPATH_W) '$(srcdir)/TestArray.cc'; fi`
+
+libtest_types_a-TestStructure.o: TestStructure.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestStructure.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestStructure.Tpo -c -o libtest_types_a-TestStructure.o `test -f 'TestStructure.cc' || echo '$(srcdir)/'`TestStructure.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestStructure.Tpo $(DEPDIR)/libtest_types_a-TestStructure.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestStructure.cc' object='libtest_types_a-TestStructure.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestStructure.o `test -f 'TestStructure.cc' || echo '$(srcdir)/'`TestStructure.cc
+
+libtest_types_a-TestStructure.obj: TestStructure.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestStructure.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestStructure.Tpo -c -o libtest_types_a-TestStructure.obj `if test -f 'TestStructure.cc'; then $(CYGPATH_W) 'TestStructure.cc'; else $(CYGPATH_W) '$(srcdir)/TestStructure.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestStructure.Tpo $(DEPDIR)/libtest_types_a-TestStructure.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestStructure.cc' object='libtest_types_a-TestStructure.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestStructure.obj `if test -f 'TestStructure.cc'; then $(CYGPATH_W) 'TestStructure.cc'; else $(CYGPATH_W) '$(srcdir)/TestStructure.cc'; fi`
+
+libtest_types_a-TestSequence.o: TestSequence.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestSequence.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestSequence.Tpo -c -o libtest_types_a-TestSequence.o `test -f 'TestSequence.cc' || echo '$(srcdir)/'`TestSequence.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestSequence.Tpo $(DEPDIR)/libtest_types_a-TestSequence.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestSequence.cc' object='libtest_types_a-TestSequence.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestSequence.o `test -f 'TestSequence.cc' || echo '$(srcdir)/'`TestSequence.cc
+
+libtest_types_a-TestSequence.obj: TestSequence.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestSequence.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestSequence.Tpo -c -o libtest_types_a-TestSequence.obj `if test -f 'TestSequence.cc'; then $(CYGPATH_W) 'TestSequence.cc'; else $(CYGPATH_W) '$(srcdir)/TestSequence.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestSequence.Tpo $(DEPDIR)/libtest_types_a-TestSequence.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestSequence.cc' object='libtest_types_a-TestSequence.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestSequence.obj `if test -f 'TestSequence.cc'; then $(CYGPATH_W) 'TestSequence.cc'; else $(CYGPATH_W) '$(srcdir)/TestSequence.cc'; fi`
+
+libtest_types_a-TestGrid.o: TestGrid.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestGrid.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestGrid.Tpo -c -o libtest_types_a-TestGrid.o `test -f 'TestGrid.cc' || echo '$(srcdir)/'`TestGrid.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestGrid.Tpo $(DEPDIR)/libtest_types_a-TestGrid.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestGrid.cc' object='libtest_types_a-TestGrid.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestGrid.o `test -f 'TestGrid.cc' || echo '$(srcdir)/'`TestGrid.cc
+
+libtest_types_a-TestGrid.obj: TestGrid.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestGrid.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestGrid.Tpo -c -o libtest_types_a-TestGrid.obj `if test -f 'TestGrid.cc'; then $(CYGPATH_W) 'TestGrid.cc'; else $(CYGPATH_W) '$(srcdir)/TestGrid.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestGrid.Tpo $(DEPDIR)/libtest_types_a-TestGrid.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestGrid.cc' object='libtest_types_a-TestGrid.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestGrid.obj `if test -f 'TestGrid.cc'; then $(CYGPATH_W) 'TestGrid.cc'; else $(CYGPATH_W) '$(srcdir)/TestGrid.cc'; fi`
+
+libtest_types_a-TestUInt32.o: TestUInt32.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestUInt32.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestUInt32.Tpo -c -o libtest_types_a-TestUInt32.o `test -f 'TestUInt32.cc' || echo '$(srcdir)/'`TestUInt32.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestUInt32.Tpo $(DEPDIR)/libtest_types_a-TestUInt32.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestUInt32.cc' object='libtest_types_a-TestUInt32.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestUInt32.o `test -f 'TestUInt32.cc' || echo '$(srcdir)/'`TestUInt32.cc
+
+libtest_types_a-TestUInt32.obj: TestUInt32.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestUInt32.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestUInt32.Tpo -c -o libtest_types_a-TestUInt32.obj `if test -f 'TestUInt32.cc'; then $(CYGPATH_W) 'TestUInt32.cc'; else $(CYGPATH_W) '$(srcdir)/TestUInt32.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestUInt32.Tpo $(DEPDIR)/libtest_types_a-TestUInt32.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestUInt32.cc' object='libtest_types_a-TestUInt32.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestUInt32.obj `if test -f 'TestUInt32.cc'; then $(CYGPATH_W) 'TestUInt32.cc'; else $(CYGPATH_W) '$(srcdir)/TestUInt32.cc'; fi`
+
+libtest_types_a-TestInt16.o: TestInt16.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestInt16.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestInt16.Tpo -c -o libtest_types_a-TestInt16.o `test -f 'TestInt16.cc' || echo '$(srcdir)/'`TestInt16.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestInt16.Tpo $(DEPDIR)/libtest_types_a-TestInt16.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestInt16.cc' object='libtest_types_a-TestInt16.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestInt16.o `test -f 'TestInt16.cc' || echo '$(srcdir)/'`TestInt16.cc
+
+libtest_types_a-TestInt16.obj: TestInt16.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestInt16.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestInt16.Tpo -c -o libtest_types_a-TestInt16.obj `if test -f 'TestInt16.cc'; then $(CYGPATH_W) 'TestInt16.cc'; else $(CYGPATH_W) '$(srcdir)/TestInt16.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestInt16.Tpo $(DEPDIR)/libtest_types_a-TestInt16.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestInt16.cc' object='libtest_types_a-TestInt16.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestInt16.obj `if test -f 'TestInt16.cc'; then $(CYGPATH_W) 'TestInt16.cc'; else $(CYGPATH_W) '$(srcdir)/TestInt16.cc'; fi`
+
+libtest_types_a-TestUInt16.o: TestUInt16.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestUInt16.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestUInt16.Tpo -c -o libtest_types_a-TestUInt16.o `test -f 'TestUInt16.cc' || echo '$(srcdir)/'`TestUInt16.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestUInt16.Tpo $(DEPDIR)/libtest_types_a-TestUInt16.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestUInt16.cc' object='libtest_types_a-TestUInt16.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestUInt16.o `test -f 'TestUInt16.cc' || echo '$(srcdir)/'`TestUInt16.cc
+
+libtest_types_a-TestUInt16.obj: TestUInt16.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestUInt16.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestUInt16.Tpo -c -o libtest_types_a-TestUInt16.obj `if test -f 'TestUInt16.cc'; then $(CYGPATH_W) 'TestUInt16.cc'; else $(CYGPATH_W) '$(srcdir)/TestUInt16.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestUInt16.Tpo $(DEPDIR)/libtest_types_a-TestUInt16.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestUInt16.cc' object='libtest_types_a-TestUInt16.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestUInt16.obj `if test -f 'TestUInt16.cc'; then $(CYGPATH_W) 'TestUInt16.cc'; else $(CYGPATH_W) '$(srcdir)/TestUInt16.cc'; fi`
+
+libtest_types_a-TestFloat32.o: TestFloat32.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestFloat32.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestFloat32.Tpo -c -o libtest_types_a-TestFloat32.o `test -f 'TestFloat32.cc' || echo '$(srcdir)/'`TestFloat32.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestFloat32.Tpo $(DEPDIR)/libtest_types_a-TestFloat32.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestFloat32.cc' object='libtest_types_a-TestFloat32.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestFloat32.o `test -f 'TestFloat32.cc' || echo '$(srcdir)/'`TestFloat32.cc
+
+libtest_types_a-TestFloat32.obj: TestFloat32.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestFloat32.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestFloat32.Tpo -c -o libtest_types_a-TestFloat32.obj `if test -f 'TestFloat32.cc'; then $(CYGPATH_W) 'TestFloat32.cc'; else $(CYGPATH_W) '$(srcdir)/TestFloat32.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestFloat32.Tpo $(DEPDIR)/libtest_types_a-TestFloat32.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestFloat32.cc' object='libtest_types_a-TestFloat32.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestFloat32.obj `if test -f 'TestFloat32.cc'; then $(CYGPATH_W) 'TestFloat32.cc'; else $(CYGPATH_W) '$(srcdir)/TestFloat32.cc'; fi`
+
+libtest_types_a-TestTypeFactory.o: TestTypeFactory.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestTypeFactory.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestTypeFactory.Tpo -c -o libtest_types_a-TestTypeFactory.o `test -f 'TestTypeFactory.cc' || echo '$(srcdir)/'`TestTypeFactory.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestTypeFactory.Tpo $(DEPDIR)/libtest_types_a-TestTypeFactory.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestTypeFactory.cc' object='libtest_types_a-TestTypeFactory.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestTypeFactory.o `test -f 'TestTypeFactory.cc' || echo '$(srcdir)/'`TestTypeFactory.cc
+
+libtest_types_a-TestTypeFactory.obj: TestTypeFactory.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestTypeFactory.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestTypeFactory.Tpo -c -o libtest_types_a-TestTypeFactory.obj `if test -f 'TestTypeFactory.cc'; then $(CYGPATH_W) 'TestTypeFactory.cc'; else $(CYGPATH_W) '$(srcdir)/TestTypeFactory.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestTypeFactory.Tpo $(DEPDIR)/libtest_types_a-TestTypeFactory.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestTypeFactory.cc' object='libtest_types_a-TestTypeFactory.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestTypeFactory.obj `if test -f 'TestTypeFactory.cc'; then $(CYGPATH_W) 'TestTypeFactory.cc'; else $(CYGPATH_W) '$(srcdir)/TestTypeFactory.cc'; fi`
+
+libtest_types_a-D4TestTypeFactory.o: D4TestTypeFactory.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-D4TestTypeFactory.o -MD -MP -MF $(DEPDIR)/libtest_types_a-D4TestTypeFactory.Tpo -c -o libtest_types_a-D4TestTypeFactory.o `test -f 'D4TestTypeFactory.cc' || echo '$(srcdir)/'`D4TestTypeFactory.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-D4TestTypeFactory.Tpo $(DEPDIR)/libtest_types_a-D4TestTypeFactory.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4TestTypeFactory.cc' object='libtest_types_a-D4TestTypeFactory.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-D4TestTypeFactory.o `test -f 'D4TestTypeFactory.cc' || echo '$(srcdir)/'`D4TestTypeFactory.cc
+
+libtest_types_a-D4TestTypeFactory.obj: D4TestTypeFactory.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-D4TestTypeFactory.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-D4TestTypeFactory.Tpo -c -o libtest_types_a-D4TestTypeFactory.obj `if test -f 'D4TestTypeFactory.cc'; then $(CYGPATH_W) 'D4TestTypeFactory.cc'; else $(CYGPATH_W) '$(srcdir)/D4TestTypeFactory.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-D4TestTypeFactory.Tpo $(DEPDIR)/libtest_types_a-D4TestTypeFactory.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4TestTypeFactory.cc' object='libtest_types_a-D4TestTypeFactory.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-D4TestTypeFactory.obj `if test -f 'D4TestTypeFactory.cc'; then $(CYGPATH_W) 'D4TestTypeFactory.cc'; else $(CYGPATH_W) '$(srcdir)/D4TestTypeFactory.cc'; fi`
+
+libtest_types_a-TestD4Group.o: TestD4Group.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestD4Group.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestD4Group.Tpo -c -o libtest_types_a-TestD4Group.o `test -f 'TestD4Group.cc' || echo '$(srcdir)/'`TestD4Group.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestD4Group.Tpo $(DEPDIR)/libtest_types_a-TestD4Group.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestD4Group.cc' object='libtest_types_a-TestD4Group.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestD4Group.o `test -f 'TestD4Group.cc' || echo '$(srcdir)/'`TestD4Group.cc
+
+libtest_types_a-TestD4Group.obj: TestD4Group.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestD4Group.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestD4Group.Tpo -c -o libtest_types_a-TestD4Group.obj `if test -f 'TestD4Group.cc'; then $(CYGPATH_W) 'TestD4Group.cc'; else $(CYGPATH_W) '$(srcdir)/TestD4Group.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestD4Group.Tpo $(DEPDIR)/libtest_types_a-TestD4Group.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestD4Group.cc' object='libtest_types_a-TestD4Group.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestD4Group.obj `if test -f 'TestD4Group.cc'; then $(CYGPATH_W) 'TestD4Group.cc'; else $(CYGPATH_W) '$(srcdir)/TestD4Group.cc'; fi`
+
+libtest_types_a-TestInt8.o: TestInt8.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestInt8.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestInt8.Tpo -c -o libtest_types_a-TestInt8.o `test -f 'TestInt8.cc' || echo '$(srcdir)/'`TestInt8.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestInt8.Tpo $(DEPDIR)/libtest_types_a-TestInt8.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestInt8.cc' object='libtest_types_a-TestInt8.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestInt8.o `test -f 'TestInt8.cc' || echo '$(srcdir)/'`TestInt8.cc
+
+libtest_types_a-TestInt8.obj: TestInt8.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestInt8.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestInt8.Tpo -c -o libtest_types_a-TestInt8.obj `if test -f 'TestInt8.cc'; then $(CYGPATH_W) 'TestInt8.cc'; else $(CYGPATH_W) '$(srcdir)/TestInt8.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestInt8.Tpo $(DEPDIR)/libtest_types_a-TestInt8.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestInt8.cc' object='libtest_types_a-TestInt8.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestInt8.obj `if test -f 'TestInt8.cc'; then $(CYGPATH_W) 'TestInt8.cc'; else $(CYGPATH_W) '$(srcdir)/TestInt8.cc'; fi`
+
+libtest_types_a-TestInt64.o: TestInt64.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestInt64.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestInt64.Tpo -c -o libtest_types_a-TestInt64.o `test -f 'TestInt64.cc' || echo '$(srcdir)/'`TestInt64.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestInt64.Tpo $(DEPDIR)/libtest_types_a-TestInt64.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestInt64.cc' object='libtest_types_a-TestInt64.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestInt64.o `test -f 'TestInt64.cc' || echo '$(srcdir)/'`TestInt64.cc
+
+libtest_types_a-TestInt64.obj: TestInt64.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestInt64.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestInt64.Tpo -c -o libtest_types_a-TestInt64.obj `if test -f 'TestInt64.cc'; then $(CYGPATH_W) 'TestInt64.cc'; else $(CYGPATH_W) '$(srcdir)/TestInt64.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestInt64.Tpo $(DEPDIR)/libtest_types_a-TestInt64.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestInt64.cc' object='libtest_types_a-TestInt64.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestInt64.obj `if test -f 'TestInt64.cc'; then $(CYGPATH_W) 'TestInt64.cc'; else $(CYGPATH_W) '$(srcdir)/TestInt64.cc'; fi`
+
+libtest_types_a-TestUInt64.o: TestUInt64.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestUInt64.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestUInt64.Tpo -c -o libtest_types_a-TestUInt64.o `test -f 'TestUInt64.cc' || echo '$(srcdir)/'`TestUInt64.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestUInt64.Tpo $(DEPDIR)/libtest_types_a-TestUInt64.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestUInt64.cc' object='libtest_types_a-TestUInt64.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestUInt64.o `test -f 'TestUInt64.cc' || echo '$(srcdir)/'`TestUInt64.cc
+
+libtest_types_a-TestUInt64.obj: TestUInt64.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestUInt64.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestUInt64.Tpo -c -o libtest_types_a-TestUInt64.obj `if test -f 'TestUInt64.cc'; then $(CYGPATH_W) 'TestUInt64.cc'; else $(CYGPATH_W) '$(srcdir)/TestUInt64.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestUInt64.Tpo $(DEPDIR)/libtest_types_a-TestUInt64.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestUInt64.cc' object='libtest_types_a-TestUInt64.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestUInt64.obj `if test -f 'TestUInt64.cc'; then $(CYGPATH_W) 'TestUInt64.cc'; else $(CYGPATH_W) '$(srcdir)/TestUInt64.cc'; fi`
+
+libtest_types_a-TestD4Sequence.o: TestD4Sequence.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestD4Sequence.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestD4Sequence.Tpo -c -o libtest_types_a-TestD4Sequence.o `test -f 'TestD4Sequence.cc' || echo '$(srcdir)/'`TestD4Sequence.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestD4Sequence.Tpo $(DEPDIR)/libtest_types_a-TestD4Sequence.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestD4Sequence.cc' object='libtest_types_a-TestD4Sequence.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestD4Sequence.o `test -f 'TestD4Sequence.cc' || echo '$(srcdir)/'`TestD4Sequence.cc
+
+libtest_types_a-TestD4Sequence.obj: TestD4Sequence.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestD4Sequence.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestD4Sequence.Tpo -c -o libtest_types_a-TestD4Sequence.obj `if test -f 'TestD4Sequence.cc'; then $(CYGPATH_W) 'TestD4Sequence.cc'; else $(CYGPATH_W) '$(srcdir)/TestD4Sequence.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestD4Sequence.Tpo $(DEPDIR)/libtest_types_a-TestD4Sequence.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestD4Sequence.cc' object='libtest_types_a-TestD4Sequence.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestD4Sequence.obj `if test -f 'TestD4Sequence.cc'; then $(CYGPATH_W) 'TestD4Sequence.cc'; else $(CYGPATH_W) '$(srcdir)/TestD4Sequence.cc'; fi`
+
+libtest_types_a-TestD4Enum.o: TestD4Enum.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestD4Enum.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestD4Enum.Tpo -c -o libtest_types_a-TestD4Enum.o `test -f 'TestD4Enum.cc' || echo '$(srcdir)/'`TestD4Enum.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestD4Enum.Tpo $(DEPDIR)/libtest_types_a-TestD4Enum.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestD4Enum.cc' object='libtest_types_a-TestD4Enum.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestD4Enum.o `test -f 'TestD4Enum.cc' || echo '$(srcdir)/'`TestD4Enum.cc
+
+libtest_types_a-TestD4Enum.obj: TestD4Enum.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestD4Enum.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestD4Enum.Tpo -c -o libtest_types_a-TestD4Enum.obj `if test -f 'TestD4Enum.cc'; then $(CYGPATH_W) 'TestD4Enum.cc'; else $(CYGPATH_W) '$(srcdir)/TestD4Enum.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestD4Enum.Tpo $(DEPDIR)/libtest_types_a-TestD4Enum.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestD4Enum.cc' object='libtest_types_a-TestD4Enum.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestD4Enum.obj `if test -f 'TestD4Enum.cc'; then $(CYGPATH_W) 'TestD4Enum.cc'; else $(CYGPATH_W) '$(srcdir)/TestD4Enum.cc'; fi`
+
+libtest_types_a-TestD4Opaque.o: TestD4Opaque.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestD4Opaque.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestD4Opaque.Tpo -c -o libtest_types_a-TestD4Opaque.o `test -f 'TestD4Opaque.cc' || echo '$(srcdir)/'`TestD4Opaque.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestD4Opaque.Tpo $(DEPDIR)/libtest_types_a-TestD4Opaque.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestD4Opaque.cc' object='libtest_types_a-TestD4Opaque.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestD4Opaque.o `test -f 'TestD4Opaque.cc' || echo '$(srcdir)/'`TestD4Opaque.cc
+
+libtest_types_a-TestD4Opaque.obj: TestD4Opaque.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestD4Opaque.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestD4Opaque.Tpo -c -o libtest_types_a-TestD4Opaque.obj `if test -f 'TestD4Opaque.cc'; then $(CYGPATH_W) 'TestD4Opaque.cc'; else $(CYGPATH_W) '$(srcdir)/TestD4Opaque.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestD4Opaque.Tpo $(DEPDIR)/libtest_types_a-TestD4Opaque.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestD4Opaque.cc' object='libtest_types_a-TestD4Opaque.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestD4Opaque.obj `if test -f 'TestD4Opaque.cc'; then $(CYGPATH_W) 'TestD4Opaque.cc'; else $(CYGPATH_W) '$(srcdir)/TestD4Opaque.cc'; fi`
+
+libtest_types_a-TestFunction.o: TestFunction.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestFunction.o -MD -MP -MF $(DEPDIR)/libtest_types_a-TestFunction.Tpo -c -o libtest_types_a-TestFunction.o `test -f 'TestFunction.cc' || echo '$(srcdir)/'`TestFunction.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestFunction.Tpo $(DEPDIR)/libtest_types_a-TestFunction.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestFunction.cc' object='libtest_types_a-TestFunction.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestFunction.o `test -f 'TestFunction.cc' || echo '$(srcdir)/'`TestFunction.cc
+
+libtest_types_a-TestFunction.obj: TestFunction.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-TestFunction.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-TestFunction.Tpo -c -o libtest_types_a-TestFunction.obj `if test -f 'TestFunction.cc'; then $(CYGPATH_W) 'TestFunction.cc'; else $(CYGPATH_W) '$(srcdir)/TestFunction.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-TestFunction.Tpo $(DEPDIR)/libtest_types_a-TestFunction.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='TestFunction.cc' object='libtest_types_a-TestFunction.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-TestFunction.obj `if test -f 'TestFunction.cc'; then $(CYGPATH_W) 'TestFunction.cc'; else $(CYGPATH_W) '$(srcdir)/TestFunction.cc'; fi`
+
+libtest_types_a-D4TestFunction.o: D4TestFunction.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-D4TestFunction.o -MD -MP -MF $(DEPDIR)/libtest_types_a-D4TestFunction.Tpo -c -o libtest_types_a-D4TestFunction.o `test -f 'D4TestFunction.cc' || echo '$(srcdir)/'`D4TestFunction.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-D4TestFunction.Tpo $(DEPDIR)/libtest_types_a-D4TestFunction.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4TestFunction.cc' object='libtest_types_a-D4TestFunction.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-D4TestFunction.o `test -f 'D4TestFunction.cc' || echo '$(srcdir)/'`D4TestFunction.cc
+
+libtest_types_a-D4TestFunction.obj: D4TestFunction.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -MT libtest_types_a-D4TestFunction.obj -MD -MP -MF $(DEPDIR)/libtest_types_a-D4TestFunction.Tpo -c -o libtest_types_a-D4TestFunction.obj `if test -f 'D4TestFunction.cc'; then $(CYGPATH_W) 'D4TestFunction.cc'; else $(CYGPATH_W) '$(srcdir)/D4TestFunction.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libtest_types_a-D4TestFunction.Tpo $(DEPDIR)/libtest_types_a-D4TestFunction.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='D4TestFunction.cc' object='libtest_types_a-D4TestFunction.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtest_types_a_CXXFLAGS) $(CXXFLAGS) -c -o libtest_types_a-D4TestFunction.obj `if test -f 'D4TestFunction.cc'; then $(CYGPATH_W) 'D4TestFunction.cc'; else $(CYGPATH_W) '$(srcdir)/D4TestFunction.cc'; fi`
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -1187,6 +1586,7 @@ install-strip:
 mostlyclean-generic:
 
 clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -1287,20 +1687,20 @@ uninstall-am: uninstall-libLIBRARIES uninstall-testheadersHEADERS
 	uninstall-testheadersHEADERS
 
 
-#check-local: check-das check-dds
-
-#check-das: atconfig atlocal $(DASTESTSUITE)
-#	$(SHELL) $(DASTESTSUITE) $(DASTESTSUITEFLAGS)
-
-#check-dds: atconfig atlocal $(DDSTESTSUITE)
-#	$(SHELL) $(DDSTESTSUITE) $(DDSTESTSUITEFLAGS)
+dmr-testsuite.tar.gz: dmr-testsuite/*.xml
+	tar -czf $@ $^
 
+# Make sure there are no spaces after the DASTESTSUITE names. jhrg 3/16/15
 clean-local:
 	test ! -f '$(DASTESTSUITE)' || $(SHELL) $(DASTESTSUITE) --clean
 	test ! -f '$(DDSTESTSUITE)' || $(SHELL) $(DDSTESTSUITE) --clean
+	test ! -f '$(EXPRTESTSUITE)' || $(SHELL) $(EXPRTESTSUITE) --clean
+	test ! -f '$(DMRTESTSUITE)' || $(SHELL) $(DMRTESTSUITE) --clean
+	test ! -f '$(GETDAPTESTSUITE)' || $(SHELL) $(GETDAPTESTSUITE) --clean
 
 distclean-local:
 	-rm atconfig
+
 $(DASTESTSUITE): $(srcdir)/DASTest.at $(srcdir)/package.m4
 	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
 	mv $@.tmp $@
@@ -1313,6 +1713,14 @@ $(EXPRTESTSUITE): $(srcdir)/EXPRTest.at $(srcdir)/package.m4
 	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
 	mv $@.tmp $@
 
+$(DMRTESTSUITE): $(srcdir)/DMRTest.at $(srcdir)/package.m4
+	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+	mv $@.tmp $@
+
+$(GETDAPTESTSUITE): $(srcdir)/getdapTest.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
 	:;{ \
diff --git a/tests/ResponseBuilder.cc b/tests/ResponseBuilder.cc
index 7270793..0c4c561 100644
--- a/tests/ResponseBuilder.cc
+++ b/tests/ResponseBuilder.cc
@@ -82,8 +82,8 @@ 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_btp_func_ce = "";
+    d_dap2ce = "";
+    d_dap2_btp_func_ce = "";
     d_timeout = 0;
 
     d_default_protocol = DAP_PROTOCOL_VERSION;
@@ -105,7 +105,7 @@ ResponseBuilder::~ResponseBuilder()
  @return A string object that contains the constraint expression. */
 string ResponseBuilder::get_ce() const
 {
-    return d_ce;
+    return d_dap2ce;
 }
 
 /** Set the constraint expression. This will filter the CE text removing
@@ -120,7 +120,7 @@ string ResponseBuilder::get_ce() const
  */
 void ResponseBuilder::set_ce(string _ce)
 {
-    d_ce = www2id(_ce, "%", "%20");
+    d_dap2ce = www2id(_ce, "%", "%20");
 }
 
 /** The ``dataset name'' is the filename or other string that the
@@ -181,6 +181,7 @@ void ResponseBuilder::establish_timeout(ostream &stream) const
     }
 #endif
 }
+#endif
 
 /**
  *  Split the CE so that the server functions that compute new values are
@@ -195,7 +196,7 @@ ResponseBuilder::split_ce(ConstraintEvaluator &eval, const string &expr)
     if (!expr.empty())
         ce = expr;
     else
-        ce = d_ce;
+        ce = d_dap2ce;
 
     string btp_function_ce = "";
     string::size_type pos = 0;
@@ -232,10 +233,11 @@ ResponseBuilder::split_ce(ConstraintEvaluator &eval, const string &expr)
     DBG(cerr << "Modified constraint: " << ce << endl);
     DBG(cerr << "BTP Function part: " << btp_function_ce << endl);
 
-    d_ce = ce;
-    d_btp_func_ce = btp_function_ce;
+    d_dap2ce = ce;
+    d_dap2_btp_func_ce = btp_function_ce;
 }
 
+#if 0
 /** 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.
@@ -325,7 +327,7 @@ void ResponseBuilder::send_das(ostream &out, DDS &dds, ConstraintEvaluator &eval
     else {
         DBG(cerr << "Simple constraint" << endl);
 
-        eval.parse_constraint(d_ce, dds); // Throws Error if the ce doesn't parse.
+        eval.parse_constraint(d_dap2ce, dds); // Throws Error if the ce doesn't parse.
 
         if (with_mime_headers)
             set_mime_text(out, dods_das, x_plain, last_modified_time(d_dataset), dds.get_dap_version());
@@ -391,13 +393,13 @@ void ResponseBuilder::send_dds(ostream &out, DDS &dds, ConstraintEvaluator &eval
         }
 
         // Server functions might mark variables to use their read()
-        // methods. Clear that so the CE in d_ce will control what is
+        // methods. Clear that so the CE in d_dap2ce will control what is
         // sent. If that is empty (there was only a function call) all
         // of the variables in the intermediate DDS (i.e., the function
         // result) will be sent.
         fdds->mark_all(false);
 
-        eval.parse_constraint(d_ce, *fdds);
+        eval.parse_constraint(d_dap2ce, *fdds);
 
         if (with_mime_headers)
             set_mime_text(out, dods_dds, x_plain, last_modified_time(d_dataset), dds.get_dap_version());
@@ -412,7 +414,7 @@ void ResponseBuilder::send_dds(ostream &out, DDS &dds, ConstraintEvaluator &eval
     else {
         DBG(cerr << "Simple constraint" << endl);
 
-        eval.parse_constraint(d_ce, dds); // Throws Error if the ce doesn't parse.
+        eval.parse_constraint(d_dap2ce, dds); // Throws Error if the ce doesn't parse.
 
         if (with_mime_headers)
             set_mime_text(out, dods_dds, x_plain, last_modified_time(d_dataset), dds.get_dap_version());
@@ -423,12 +425,12 @@ void ResponseBuilder::send_dds(ostream &out, DDS &dds, ConstraintEvaluator &eval
     out << flush;
 }
 #endif
+
 /**
  * Build/return the BLOB part of the DAP2 data response.
  */
 void ResponseBuilder::dataset_constraint(ostream &out, DDS & dds, ConstraintEvaluator & eval, bool ce_eval)
 {
-    // send constrained DDS
     DBG(cerr << "Inside dataset_constraint" << endl);
 
     dds.print_constrained(out);
@@ -467,13 +469,35 @@ void ResponseBuilder::dataset_constraint(ostream &out, DDS & dds, ConstraintEval
  @return void */
 void ResponseBuilder::send_data(ostream &data_stream, DDS &dds, ConstraintEvaluator &eval, bool with_mime_headers)
 {
-        DBG(cerr << "Simple constraint" << endl);
+    // Split constraint into two halves
+    split_ce(eval);
 
-        eval.parse_constraint(d_ce, dds); // Throws Error if the ce doesn't parse.
+    // If there are functions, parse them and eval.
+    // Use that DDS and parse the non-function ce
+    // Serialize using the second ce and the second dds
+    if (!d_dap2_btp_func_ce.empty()) {
+        DBG(cerr << "Found function(s) in CE: " << d_btp_func_ce << endl);
+        string cache_token = "";
+        DDS *fdds = 0;
+
+        // The BES code caches the function result
+            eval.parse_constraint(d_dap2_btp_func_ce, dds);
+            fdds = eval.eval_function_clauses(dds);
 
-        dds.tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
+        DBG(fdds->print_constrained(cerr));
 
-        if (dds.get_response_limit() != 0 && dds.get_request_size(true) > dds.get_response_limit()) {
+        // Server functions might mark variables to use their read()
+        // methods. Clear that so the CE in d_dap2ce will control what is
+        // sent. If that is empty (there was only a function call) all
+        // of the variables in the intermediate DDS (i.e., the function
+        // result) will be sent.
+        fdds->mark_all(false);
+
+        eval.parse_constraint(d_dap2ce, *fdds);
+
+        fdds->tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
+
+        if (fdds->get_response_limit() != 0 && fdds->get_request_size(true) > fdds->get_response_limit()) {
             string msg = "The Request for " + long_to_string(dds.get_request_size(true) / 1024)
                     + "KB is too large; requests for this user are limited to "
                     + long_to_string(dds.get_response_limit() / 1024) + "KB.";
@@ -483,6 +507,31 @@ void ResponseBuilder::send_data(ostream &data_stream, DDS &dds, ConstraintEvalua
         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;
+        DBG(cerr << "About to call dataset_constraint" << endl);
+        dataset_constraint(data_stream, *fdds, eval, false);
+
+        delete fdds;
+    }
+    else {
+
+	DBG(cerr << "Simple constraint" << endl);
+
+	eval.parse_constraint(d_dap2ce, dds); // Throws Error if the ce doesn't parse.
+
+	dds.tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
+
+	if (dds.get_response_limit() != 0 && dds.get_request_size(true) > dds.get_response_limit()) {
+		string msg = "The Request for " + long_to_string(dds.get_request_size(true) / 1024)
+				+ "KB is too large; requests for this user are limited to "
+				+ long_to_string(dds.get_response_limit() / 1024) + "KB.";
+		throw Error(msg);
+	}
+
+	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;
 }
diff --git a/tests/ResponseBuilder.h b/tests/ResponseBuilder.h
index 9cd5b65..741e084 100644
--- a/tests/ResponseBuilder.h
+++ b/tests/ResponseBuilder.h
@@ -28,8 +28,10 @@
 
 #include <string>
 
-class libdap::ConstraintEvaluator;
-class libdap::DDS;
+namespace libdap {
+
+class ConstraintEvaluator;
+class DDS;
 
 /**
  * Used for testing only. This duplicates code in the bes/dap module.
@@ -43,8 +45,8 @@ public:
 
 protected:
     std::string d_dataset;  		/// Name of the dataset/database
-    std::string d_ce;  		    /// Constraint expression
-    std::string d_btp_func_ce;   /// The BTP functions, extracted from the CE
+    std::string d_dap2ce;  		    /// Constraint expression
+    std::string d_dap2_btp_func_ce;   /// The BTP functions, extracted from the CE
     int d_timeout;  		/// Response timeout after N seconds
     std::string d_default_protocol;	/// Version std::string for the library's default protocol version
 
@@ -64,6 +66,8 @@ public:
     virtual std::string get_ce() const;
     virtual void set_ce(std::string _ce);
 
+    void split_ce(ConstraintEvaluator &eval, const string &expr = "");
+
     virtual std::string get_dataset_name() const;
     virtual void set_dataset_name(const std::string _dataset);
 
@@ -71,4 +75,5 @@ public:
     virtual void send_data(std::ostream &data_stream, libdap::DDS &dds, libdap::ConstraintEvaluator &eval, bool with_mime_headers = true);
 };
 
+}
 #endif // _response_builder_h
diff --git a/tests/TestArray.cc b/tests/TestArray.cc
index 7f15e12..e651b05 100644
--- a/tests/TestArray.cc
+++ b/tests/TestArray.cc
@@ -49,10 +49,27 @@
 
 //#define DODS_DEBUG
 
-//#include "ce_functions.h"
 #include "util.h"
 #include "debug.h"
 
+#include "TestInt8.h"
+
+#include "TestByte.h"
+#include "TestInt16.h"
+#include "TestUInt16.h"
+#include "TestInt32.h"
+#include "TestUInt32.h"
+
+#include "TestInt64.h"
+#include "TestUInt64.h"
+
+#include "TestD4Enum.h"
+
+#include "TestFloat32.h"
+#include "TestFloat64.h"
+
+#include "TestStr.h"
+
 #include "TestArray.h"
 #include "TestCommon.h"
 
@@ -72,13 +89,13 @@ 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, BaseType *v, bool is_dap4) :
+    Array(n, v, is_dap4), 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 string &n, const string &d, BaseType *v, bool is_dap4) :
+    Array(n, d, v, is_dap4), d_series_values(false)
 {
 }
 
@@ -98,22 +115,76 @@ TestArray::operator=(const TestArray &rhs)
     if (this == &rhs)
         return *this;
 
-    dynamic_cast<Array &> (*this) = rhs; // run Constructor=
+    dynamic_cast<Array &> (*this) = rhs;
 
     _duplicate(rhs);
 
     return *this;
 }
 
+
+// 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 but only variables selected in the CE have
+// values.
+
+unsigned int TestArray::m_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 = m_print_array(out, index, dims - 1, shape + 1);
+            out << ",";
+        }
+        index = m_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);
+
+    m_print_array(out, 0, dimensions(true), shape);
+
+    delete[] shape;
+    shape = 0;
+}
+
 /** 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()
+bool TestArray::m_name_is_special()
 {
     return (name().find("lat") != string::npos || name().find("lon") != string::npos);
 }
 
-void TestArray::build_special_values()
+void TestArray::m_build_special_values()
 {
     if (name().find("lat_reversed") != string::npos) {
         int array_len = length();
@@ -149,122 +220,183 @@ 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)
+/**
+ * @brief Load an 2D array with values.
+ * Use the read() function for the prototype element of the array to
+ * get values and load them into an array, then constrain the array.
+ * Thus if 'series values' are used and the array is constrained, the
+ * result will 'make sense'
+ *
+ * @param constrained_array
+ */
+template <typename T, class C>
+void TestArray::m_constrained_matrix(vector<T>&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(true)];
-    DBG(cerr << "unconstrained size: " << unconstrained_size << endl);
-
-    int elem_width = var()->width(true); // size of an element
-    char *elem_val = new char[elem_width];
 
+    vector<T> whole_array(unconstrained_size);
     for (int i = 0; i < unconstrained_size; ++i) {
+        T v;
         var()->read();
-        var()->buf2val((void **) &elem_val);
+#if 0
+        if (var()->type() == dods_enum_c)
+            static_cast<C*>(var())->value(&v);
+        else
+#endif
+            v = static_cast<C*>(var())->value();
 
-        memcpy(whole_array + i * elem_width, elem_val, elem_width);
+        whole_array[i] = v;
         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);
+    DBG(cerr << "whole_array: "; copy(whole_array.begin(), whole_array.end(), ostream_iterator<T>(cerr, ", ")); 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);
+    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) {
+            constrained_array[constrained_size++] = whole_array[m_offset(y, X, x)];
+            x += dimension_stride(X);
+        }
 
-            DBG2(cerr << "whole[" << y << "][" << x << "]: ("
-                    << m_offset(y, Y, x) << ") "
-                    << *(dods_byte*)(whole_array + m_offset(y, X, x)*elem_width)
-                    << endl);
+        y += dimension_stride(Y);
+    }
+}
 
-            memcpy(dest, whole_array + m_offset(y, X, x) * elem_width, elem_width);
+template <typename T>
+void TestArray::m_enum_constrained_matrix(vector<T>&constrained_array)
+{
+    int unconstrained_size = 1;
+    Dim_iter d = dim_begin();
+    while (d != dim_end())
+        unconstrained_size *= dimension_size(d++, false);
+
+    vector<T> whole_array(unconstrained_size);
+    for (int i = 0; i < unconstrained_size; ++i) {
+        T v;
+        var()->read();
+        static_cast<D4Enum*>(var())->value(&v);
+        whole_array[i] = v;
+        var()->set_read_p(false); // pick up the next value
+    }
+
+    DBG(cerr << "whole_array: "; copy(whole_array.begin(), whole_array.end(), ostream_iterator<T>(cerr, ", ")); cerr << endl);
 
-            dest += elem_width;
+    Dim_iter Y = dim_begin();
+    Dim_iter X = Y + 1;
+
+    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) {
+            constrained_array[constrained_size++] = whole_array[m_offset(y, X, x)];
             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 in the 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[])
+/**
+ * Load the variable's internal data buffer with values, simulating a read()
+ * call to some data store. A private method.
+ */
+template <typename T, class C>
+void TestArray::m_cardinal_type_read_helper()
 {
-    if (dims == 1) {
-        out << "{";
-        for (unsigned i = 0; i < shape[0] - 1; ++i) {
-            dynamic_cast<TestCommon&> (*var(index++)).output_values(out);
-            out << ", ";
+    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 && m_name_is_special()) {
+            m_build_special_values();
+        }
+        else if (dimensions() == 2) {
+            vector<T> tmp(length());
+            m_constrained_matrix<T, C>(tmp);
+            set_value(tmp, length());
+        }
+        else {
+            vector<T> tmp(length());
+            for (int64_t i = 0, end = length(); i < end; ++i) {
+                var()->read();
+                tmp[i] = static_cast<C*>(var())->value();
+                var()->set_read_p(false); // pick up the next value
+            }
+            set_value(tmp, length());
         }
-        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 << ",";
+        // read a value into the Array's prototype element
+        var()->read();
+        T value = static_cast<C*>(var())->value();
+        vector<T> tmp(length());
+        for (int64_t i = 0, end = length(); i < end; ++i) {
+            tmp[i] = value;
         }
-        index = print_array(out, index, dims - 1, shape + 1);
-        out << "}";
 
-        return index;
+        set_value(tmp, length());
     }
 }
 
-void TestArray::output_values(std::ostream &out)
+/**
+ * Load the variable's internal data buffer with values, simulating a read()
+ * call to some data store. A private method.
+ */
+template <typename T>
+void TestArray::m_enum_type_read_helper()
 {
-    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);
+    if (get_series_values()) {
+        if (dimensions() == 2) {
+            vector<T> tmp(length());
+            m_enum_constrained_matrix<T>(tmp);
+            set_value(tmp, length());
+        }
+        else {
+            vector<T> tmp(length());
+            for (int64_t i = 0, end = length(); i < end; ++i) {
+                var()->read();
+                T v;
+                static_cast<D4Enum*>(var())->value(&v);
 
-    print_array(out, 0, dimensions(true), shape);
+                tmp[i] = v;
+                var()->set_read_p(false); // pick up the next value
+            }
+            set_value(tmp, length());
+        }
+    }
+    else {
+        // read a value into the Array's prototype element
+        var()->read();
+        T value;
+        static_cast<D4Enum*>(var())->value(&value);
 
-    delete[] shape;
-    shape = 0;
+        vector<T> tmp(length());
+        for (int64_t i = 0, end = length(); i < end; ++i) {
+            tmp[i] = value;
+        }
+
+        set_value(tmp, length());
+    }
 }
 
 bool TestArray::read()
@@ -275,124 +407,140 @@ bool TestArray::read()
     if (test_variable_sleep_interval > 0)
         sleep(test_variable_sleep_interval);
 
-    unsigned int array_len = length(); // elements in the array
+    int64_t array_len = length(); // elements in the array
 
     switch (var()->type()) {
-        case dods_byte_c:
+		// These are the DAP2 types and the classes that implement them all define
+		// the old buf2val() and val2buf() methods. For the new DAP4 types see below.
+        //case dods_byte_c:
+        //case dods_uint8_c:
         case dods_int16_c:
+        	m_cardinal_type_read_helper<dods_int16, Int16>();
+        	break;
+
         case dods_uint16_c:
+        	m_cardinal_type_read_helper<dods_uint16, UInt16>();
+        	break;
+
         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(true));
-
-            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);
+        	m_cardinal_type_read_helper<dods_int32, Int32>();
+        	break;
 
-                for (unsigned i = 0; i < array_len; ++i) {
-                    memcpy(&tmp[0] + i * elem_wid, elem_val, elem_wid);
-                }
+       case dods_uint32_c:
+        	m_cardinal_type_read_helper<dods_uint32, UInt32>();
+        	break;
 
-                val2buf(&tmp[0]);
-            }
+        case dods_float32_c:
+        	m_cardinal_type_read_helper<dods_float32, Float32>();
+        	break;
 
-            delete elem_val;
-            elem_val = 0; // alloced in buf2val()
-            // delete[] tmp; tmp = 0;	// alloced above
+        case dods_float64_c:
+        	m_cardinal_type_read_helper<dods_float64, Float64>();
+        	break;
 
+        case dods_int8_c:
+        	m_cardinal_type_read_helper<dods_int8, Int8>();
+        	break;
+
+        case dods_byte_c:
+        case dods_char_c:
+        case dods_uint8_c:
+        	m_cardinal_type_read_helper<dods_byte, Byte>();
+        	break;
+
+        case dods_int64_c:
+        	m_cardinal_type_read_helper<dods_int64, Int64>();
+        	break;
+
+        case dods_uint64_c:
+        	m_cardinal_type_read_helper<dods_uint64, UInt64>();
+        	break;
+
+        case dods_enum_c:
+            switch (static_cast<D4Enum*>(var())->element_type()) {
+            case dods_byte_c:
+            case dods_char_c:
+            case dods_uint8_c:
+                m_enum_type_read_helper<dods_byte>();
+                break;
+            case dods_int8_c:
+                m_enum_type_read_helper<dods_int8>();
+                break;
+            case dods_int16_c:
+                m_enum_type_read_helper<dods_int16>();
+                break;
+            case dods_uint16_c:
+                m_enum_type_read_helper<dods_uint16>();
+                break;
+            case dods_int32_c:
+                m_enum_type_read_helper<dods_int32>();
+                break;
+            case dods_uint32_c:
+                m_enum_type_read_helper<dods_uint32>();
+                break;
+            case dods_int64_c:
+                m_enum_type_read_helper<dods_int64>();
+                break;
+            case dods_uint64_c:
+                m_enum_type_read_helper<dods_uint64>();
+                break;
+            default:
+                throw InternalErr(__FILE__, __LINE__, "Enum with undefined type.");
+            }
             break;
-        }
 
         case dods_str_c:
         case dods_url_c: {
-            // char *tmp = new char[width()];
-            vector<char> tmp(width(true));
-            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;
+        	vector<string> tmp(array_len);
+
+			if (get_series_values()) {
+				for (int64_t i = 0; i < array_len; ++i) {
+					var()->read();
+					// URL isa Str
+					tmp[i] = static_cast<Str*>(var())->value();
+					var()->set_read_p(false); // pick up the next value
+				}
+			}
+			else {
+				var()->read();
+				string value = static_cast<Str*>(var())->value();
+
+				for (unsigned i = 0; i < array_len; ++i)
+					tmp[i] = value;
+			}
+
+			set_value(tmp, array_len);
+			break;
         }
 
+        case dods_opaque_c:
         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.
-
+            	// Copy the prototype and read a value into it
                 BaseType *elem = var()->ptr_duplicate();
-
-                // read values into the new instance.
-
                 elem->read();
+                // Load the new value into this object's array
+                set_vec(i, elem);
+            }
+
+            break;
 
-                // now load the new instance in the array.
+        case dods_sequence_c:
+            // No sequence arrays in DAP2
+        	if (!is_dap4())
+        		throw InternalErr(__FILE__, __LINE__, "Bad data type");
 
+            for (unsigned i = 0; i < array_len; ++i) {
+            	// Copy the prototype and read a value into it
+                BaseType *elem = var()->ptr_duplicate();
+                //elem->read();
+                // Load the new value into this object's array
                 set_vec(i, elem);
             }
 
             break;
 
-        case dods_sequence_c:
+            // No Grids in DAP4; No arrays of arrays and no null-typed vars in DAP2 or 4
         case dods_grid_c:
         case dods_array_c:
         case dods_null_c:
diff --git a/tests/TestArray.h b/tests/TestArray.h
index 98a3bd4..487d1de 100644
--- a/tests/TestArray.h
+++ b/tests/TestArray.h
@@ -44,13 +44,22 @@ using namespace libdap ;
 class TestArray: public Array, public TestCommon {
     bool d_series_values;
     void _duplicate(const TestArray &ts);
+    unsigned int m_print_array(ostream &out, unsigned int index, unsigned int dims, unsigned int shape[]);
+
+    bool m_name_is_special();
+    void m_build_special_values();
+
     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[]);
+
+    template <typename T, class C> void m_constrained_matrix(vector<T> &constrained_array);
+    template <typename T> void m_enum_constrained_matrix(vector<T> &constrained_array);
+
+    template <typename T, class C> void m_cardinal_type_read_helper();
+    template <typename T> void m_enum_type_read_helper();
 
 public:
-    TestArray(const string &n, BaseType *v);
-    TestArray(const string &n, const string &d, BaseType *v);
+    TestArray(const string &n, BaseType *v, bool is_dap4 = false);
+    TestArray(const string &n, const string &d, BaseType *v, bool is_dap4 = false);
     TestArray(const TestArray &rhs);
 
     virtual ~TestArray();
@@ -60,9 +69,6 @@ public:
     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);
 
diff --git a/tests/TestByte.cc b/tests/TestByte.cc
index 25d1ca8..61ed631 100644
--- a/tests/TestByte.cc
+++ b/tests/TestByte.cc
@@ -84,13 +84,20 @@ TestByte::_duplicate(const TestByte &ts)
 
 TestByte::TestByte(const string &n) : Byte(n), d_series_values(false)
 {
-    d_buf = 255;
+	// For some reason, d_buf was set to '23' in the version checked in on
+	// 9/12/13, but that seems to break the EXPR regression tests and '255'
+	// seems to be the correct value. Since '23' is an odd choice, I'm leaving
+	// this comment as a reminder should this information be useful in the future.
+	// jhrg 10/1/13
+    // d_buf = 23;
+	d_buf = 255;
 }
 
 TestByte::TestByte(const string &n, const string &d)
     : Byte(n, d), d_series_values(false)
 {
-    d_buf = 255;
+    // d_buf = 23;
+	d_buf = 255;
 }
 
 BaseType *
diff --git a/tests/TestByte.h b/tests/TestByte.h
index 5c3e377..187ac0a 100644
--- a/tests/TestByte.h
+++ b/tests/TestByte.h
@@ -11,18 +11,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
 //
@@ -33,7 +33,7 @@
 // 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. 
+// 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
@@ -68,11 +68,11 @@ public:
     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; }
+
+    virtual void set_series_values(bool sv) { d_series_values = sv; }
+    virtual bool get_series_values() { return d_series_values; }
 };
 
 #endif // _testbyte_h
diff --git a/tests/TestCommon.cc b/tests/TestCommon.cc
deleted file mode 100644
index 4f683b1..0000000
--- a/tests/TestCommon.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-#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
index 071a9df..1567387 100644
--- a/tests/TestCommon.h
+++ b/tests/TestCommon.h
@@ -28,40 +28,37 @@
 #ifndef _test_common_h
 #define _test_common_h 1
 
-#include <stdio.h>
+// #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();
+    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.
+    /** Write out values. Does not test the read_p property first.
 
         @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()
+        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();
+    /**
+     * Set the series_value property.
+     * @see get_series_values
+     * @param state True if the values returned by read() should mimic the DTS,
+     * false if they should be static.
+     */
+    virtual void set_series_values(bool state) = 0;
+
+    /** 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. */
+    virtual bool get_series_values() = 0;
 };
 
 #endif // _test_common_h
diff --git a/tests/TestUInt16.cc b/tests/TestD4Enum.cc
similarity index 55%
copy from tests/TestUInt16.cc
copy to tests/TestD4Enum.cc
index fbc5d97..e6c5a70 100644
--- a/tests/TestUInt16.cc
+++ b/tests/TestD4Enum.cc
@@ -11,32 +11,21 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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
+#ifndef WIN64
 #include <unistd.h>
 #else
 #include <io.h>
@@ -44,76 +33,81 @@
 #include <process.h>
 #endif
 
-#include "TestUInt16.h"
+//#define DODS_DEBUG
+
+#include "TestD4Enum.h"
+#include "debug.h"
 
 extern int test_variable_sleep_interval;
 
 void
-TestUInt16::_duplicate(const TestUInt16 &ts)
+TestD4Enum::_duplicate(const TestD4Enum &ts)
 {
     d_series_values = ts.d_series_values;
 }
 
-
-TestUInt16::TestUInt16(const string &n) : UInt16(n), d_series_values(false)
+TestD4Enum::TestD4Enum(const string &n, Type t) : D4Enum(n, t), TestCommon(), d_series_values(false)
 {
-    d_buf = 1;
+    set_value(0);
 }
 
-TestUInt16::TestUInt16(const string &n, const string &d)
-    : UInt16(n, d), d_series_values(false)
+TestD4Enum::TestD4Enum(const string &n, const string &d, Type t)
+    : D4Enum(n, d, t), TestCommon(), d_series_values(false)
 {
-    d_buf = 1;
+    set_value(0);
 }
 
-TestUInt16::TestUInt16(const TestUInt16 &rhs) : UInt16(rhs), TestCommon(rhs)
+TestD4Enum::TestD4Enum(const TestD4Enum &rhs) : D4Enum(rhs), TestCommon(rhs)
 {
     _duplicate(rhs);
 }
 
-TestUInt16 &
-TestUInt16::operator=(const TestUInt16 &rhs)
+TestD4Enum &
+TestD4Enum::operator=(const TestD4Enum &rhs)
 {
     if (this == &rhs)
 	return *this;
 
-    dynamic_cast<UInt16 &>(*this) = rhs; // run Constructor=
+    dynamic_cast<D4Enum &>(*this) = rhs; // run Constructor=
 
     _duplicate(rhs);
 
     return *this;
 }
 
-
 BaseType *
-TestUInt16::ptr_duplicate()
+TestD4Enum::ptr_duplicate()
 {
-    return new TestUInt16(*this);
+    return new TestD4Enum(*this);
 }
 
-void 
-TestUInt16::output_values(std::ostream &out)
+void
+TestD4Enum::output_values(std::ostream &out)
 {
     print_val(out, "", false);
 }
 
-bool
-TestUInt16::read()
-{
-    if (read_p())
-	return true;
+bool TestD4Enum::read() {
+    DBG(cerr << "Entering TestD4Enum::read for " << name() << endl);
+    if (read_p()) return true;
 
-    if (test_variable_sleep_interval > 0)
-	sleep(test_variable_sleep_interval);
+    if (test_variable_sleep_interval > 0) sleep(test_variable_sleep_interval);
 
     if (get_series_values()) {
-        d_buf = (short)(16 * d_buf);
+        int64_t v;
+        value(&v);
+        if (v == 3)
+            set_value(1);
+        else
+            set_value(v + 1);
     }
     else {
-        d_buf = 64000;
+        set_value((uint64_t)1);
     }
-    
+
     set_read_p(true);
-    
+
+    DBG(cerr << "In TestD4Enum::read, _buf = " << d_buf.i64 << endl);
+
     return true;
 }
diff --git a/tests/TestStructure.h b/tests/TestD4Enum.h
similarity index 57%
copy from tests/TestStructure.h
copy to tests/TestD4Enum.h
index 526a542..c04992b 100644
--- a/tests/TestStructure.h
+++ b/tests/TestD4Enum.h
@@ -11,57 +11,49 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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 _testd4enum_h
+#define _testd4enum_h 1
 
-#ifndef _teststructure_h
-#define _teststructure_h 1
 
-#include "Structure.h"
+#include "D4Enum.h"
 #include "TestCommon.h"
 
 using namespace libdap ;
 
-class TestStructure: public Structure, public TestCommon {
+class TestD4Enum: public D4Enum, public TestCommon {
     bool d_series_values;
-    void _duplicate(const TestStructure &ts);
+    void _duplicate(const TestD4Enum &ts);
 
 public:
-    TestStructure(const string &n);
-    TestStructure(const string &n, const string &d);
-    TestStructure(const TestStructure &rhs);
+    TestD4Enum(const string &n, Type t);
+    TestD4Enum(const string &n, const string &d, Type t);
+    TestD4Enum(const TestD4Enum &rhs);
 
-    virtual ~TestStructure();
+    virtual ~TestD4Enum() {}
 
-    TestStructure &operator=(const TestStructure &rhs);
+    TestD4Enum &operator=(const TestD4Enum &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 void set_series_values(bool sv) { d_series_values = sv; }
+    virtual bool get_series_values() { return d_series_values; }
 };
 
-#endif // _teststructure_h
+#endif //_testd4enum_h
+
diff --git a/tests/TestStructure.cc b/tests/TestD4Group.cc
similarity index 52%
copy from tests/TestStructure.cc
copy to tests/TestD4Group.cc
index 2b5300d..7fec260 100644
--- a/tests/TestStructure.cc
+++ b/tests/TestD4Group.cc
@@ -4,7 +4,7 @@
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
 // Access Protocol.
 
-// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Copyright (c) 2013 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -19,72 +19,63 @@
 //
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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 "TestD4Group.h"
+
 #include "debug.h"
 
 void
-TestStructure::_duplicate(const TestStructure &ts)
+TestD4Group::m_duplicate(const TestD4Group &ts)
 {
     d_series_values = ts.d_series_values;
 }
 
-BaseType *
-TestStructure::ptr_duplicate()
+TestD4Group *
+TestD4Group::ptr_duplicate()
 {
-    return new TestStructure(*this);
+    return new TestD4Group(*this);
 }
 
-TestStructure::TestStructure(const TestStructure &rhs) : Structure(rhs), TestCommon(rhs)
+TestD4Group::TestD4Group(const TestD4Group &rhs) : D4Group(rhs), TestCommon(rhs)
 {
-    _duplicate(rhs);
+    m_duplicate(rhs);
 }
 
-TestStructure &
-TestStructure::operator=(const TestStructure &rhs)
+TestD4Group &
+TestD4Group::operator=(const TestD4Group &rhs)
 {
     if (this == &rhs)
 	return *this;
 
-    dynamic_cast<Structure &>(*this) = rhs; // run Constructor=
+    dynamic_cast<D4Group &>(*this) = rhs; // run Constructor=
 
-    _duplicate(rhs);
+    m_duplicate(rhs);
 
     return *this;
 }
 
-TestStructure::TestStructure(const string &n) : Structure(n),
-        d_series_values(false)
+TestD4Group::TestD4Group(const string &n) : D4Group(n), d_series_values(false)
 {
 }
 
-TestStructure::TestStructure(const string &n, const string &d)
-    : Structure(n, d), d_series_values(false)
+TestD4Group::TestD4Group(const string &n, const string &d)
+    : D4Group(n, d), d_series_values(false)
 {
 }
 
-TestStructure::~TestStructure()
+TestD4Group::~TestD4Group()
 {
 }
 
 void
-TestStructure::output_values(std::ostream &out)
+TestD4Group::output_values(std::ostream &out)
 {
     out << "{ " ;
 
@@ -115,36 +106,31 @@ TestStructure::output_values(std::ostream &out)
     out << " }" ;
 }
 
-// For this `Test' class, run the read mfunc for each of variables which
-// comprise the structure.
-
-bool
-TestStructure::read()
+bool TestD4Group::read()
 {
-    if (read_p())
-	return true;
+	if (read_p()) return true;
 
-    for (Vars_iter i = var_begin(); i != var_end(); i++)
-    {
-	if (!(*i)->read())
-	{
-	    return false;
+	for (Vars_iter i = var_begin(); i != var_end(); i++) {
+		if (!(*i)->read()) {
+			return false;
+		}
 	}
-    }
 
-    set_read_p(true);
+	set_read_p(true);
 
-    return true;
+	return true;
 }
 
-void
-TestStructure::set_series_values(bool sv)
+void TestD4Group::set_series_values(bool sv)
 {
-    Vars_iter i = var_begin();
-    while (i != var_end()) {
-        dynamic_cast<TestCommon&>(*(*i)).set_series_values(sv);
-        ++i;
-    }
+	Vars_iter i = var_begin();
+	while (i != var_end()) {
+		TestCommon *tc = dynamic_cast<TestCommon*>(*i);
+		if (!tc)
+		    throw InternalErr (__FILE__, __LINE__, "Variable '" + (*i)->name() + "' is not a TestCommon.");
+		tc->set_series_values(sv);
+		++i;
+	}
 
-    d_series_values = sv;
+	d_series_values = sv;
 }
diff --git a/tests/TestStructure.h b/tests/TestD4Group.h
similarity index 58%
copy from tests/TestStructure.h
copy to tests/TestD4Group.h
index 526a542..86746d5 100644
--- a/tests/TestStructure.h
+++ b/tests/TestD4Group.h
@@ -4,64 +4,54 @@
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
 // Access Protocol.
 
-// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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
+#ifndef _test_d4_group_h
+#define _test_d4_group_h 1
 
-#include "Structure.h"
+#include "D4Group.h"
 #include "TestCommon.h"
 
 using namespace libdap ;
 
-class TestStructure: public Structure, public TestCommon {
+class TestD4Group: public D4Group, public TestCommon {
     bool d_series_values;
-    void _duplicate(const TestStructure &ts);
+    void m_duplicate(const TestD4Group &ts);
 
 public:
-    TestStructure(const string &n);
-    TestStructure(const string &n, const string &d);
-    TestStructure(const TestStructure &rhs);
+    TestD4Group(const string &n);
+    TestD4Group(const string &n, const string &d);
+    TestD4Group(const TestD4Group &rhs);
 
-    virtual ~TestStructure();
+    virtual ~TestD4Group();
 
-    TestStructure &operator=(const TestStructure &rhs);
+    TestD4Group &operator=(const TestD4Group &rhs);
 
-    virtual BaseType *ptr_duplicate();
+    virtual TestD4Group *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
+#endif // _test_d4_group_h
diff --git a/tests/TestD4Opaque.cc b/tests/TestD4Opaque.cc
new file mode 100644
index 0000000..8905c50
--- /dev/null
+++ b/tests/TestD4Opaque.cc
@@ -0,0 +1,122 @@
+
+// -*- 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"
+
+#ifndef WIN64
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+//#define DODS_DEBUG
+
+#include "TestD4Opaque.h"
+#include "debug.h"
+
+extern int test_variable_sleep_interval;
+
+void
+TestD4Opaque::m_duplicate(const TestD4Opaque &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+void
+TestD4Opaque::m_set_values(int start)
+{
+    dods_opaque values;
+    values.push_back(start);
+    values.push_back(2 * start);
+    values.push_back(3 * start);
+    values.push_back(4 * start);
+    values.push_back(5 * start);
+
+    set_value(values);
+}
+
+TestD4Opaque::TestD4Opaque(const string &n) : D4Opaque(n), d_series_values(false)
+{
+}
+
+TestD4Opaque::TestD4Opaque(const string &n, const string &d) : D4Opaque(n, d), d_series_values(false)
+{
+}
+
+TestD4Opaque::TestD4Opaque(const TestD4Opaque &rhs) : D4Opaque(rhs), TestCommon(rhs)
+{
+    m_duplicate(rhs);
+}
+
+TestD4Opaque &
+TestD4Opaque::operator=(const TestD4Opaque &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<D4Opaque &>(*this) = rhs; // run Constructor=
+
+    m_duplicate(rhs);
+
+    return *this;
+}
+
+BaseType *
+TestD4Opaque::ptr_duplicate()
+{
+    return new TestD4Opaque(*this);
+}
+
+void
+TestD4Opaque::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool TestD4Opaque::read() {
+    DBG(cerr << "Entering TestD4Opaque::read for " << name() << endl);
+    if (read_p()) return true;
+
+    if (test_variable_sleep_interval > 0) sleep(test_variable_sleep_interval);
+
+    if (get_series_values()) {
+        dods_opaque vals = value();
+        m_set_values(vals[0] * 2);
+    }
+    else {
+        m_set_values(1);
+    }
+
+    set_read_p(true);
+
+    DBG(cerr << "In TestD4Opaque::read, d_buf = ");
+    DBGN(ostream_iterator<uint8_t> out_it (cerr," "));
+    DBGN(std::copy ( d_buf.begin(), d_buf.end(), out_it ));
+    DBGN(cerr << endl);
+
+    return true;
+}
diff --git a/tests/TestStructure.h b/tests/TestD4Opaque.h
similarity index 57%
copy from tests/TestStructure.h
copy to tests/TestD4Opaque.h
index 526a542..80d8e86 100644
--- a/tests/TestStructure.h
+++ b/tests/TestD4Opaque.h
@@ -11,57 +11,50 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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
+#ifndef _testd4opaque_h
+#define _testd4opaque_h 1
 
-#include "Structure.h"
+#include "D4Opaque.h"
 #include "TestCommon.h"
 
 using namespace libdap ;
 
-class TestStructure: public Structure, public TestCommon {
+class TestD4Opaque: public D4Opaque, public TestCommon {
     bool d_series_values;
-    void _duplicate(const TestStructure &ts);
+
+    void m_duplicate(const TestD4Opaque &ts);
+    void m_set_values(int start);
 
 public:
-    TestStructure(const string &n);
-    TestStructure(const string &n, const string &d);
-    TestStructure(const TestStructure &rhs);
+    TestD4Opaque(const string &n);
+    TestD4Opaque(const string &n, const string &d);
+    TestD4Opaque(const TestD4Opaque &rhs);
 
-    virtual ~TestStructure();
+    virtual ~TestD4Opaque() {}
 
-    TestStructure &operator=(const TestStructure &rhs);
+    TestD4Opaque &operator=(const TestD4Opaque &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 void set_series_values(bool sv) { d_series_values = sv; }
+    virtual bool get_series_values() { return d_series_values; }
 };
 
-#endif // _teststructure_h
+#endif //_testd4opaque_h
+
diff --git a/tests/TestD4Sequence.cc b/tests/TestD4Sequence.cc
new file mode 100644
index 0000000..0d5eb72
--- /dev/null
+++ b/tests/TestD4Sequence.cc
@@ -0,0 +1,120 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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
+
+#include "TestD4Sequence.h"
+#include "TestCommon.h"
+
+#include "debug.h"
+
+void
+TestD4Sequence::m_duplicate(const TestD4Sequence &ts)
+{
+    d_current = ts.d_current;
+    d_len = ts.d_len;
+    d_series_values = ts.d_series_values;
+}
+
+BaseType *
+TestD4Sequence::ptr_duplicate()
+{
+    return new TestD4Sequence(*this);
+}
+
+TestD4Sequence::TestD4Sequence(const string &n) : D4Sequence(n), d_len(4),
+	d_current(0), d_series_values(false)
+{
+}
+
+TestD4Sequence::TestD4Sequence(const string &n, const string &d)
+    : D4Sequence(n, d), d_len(4), d_current(0), d_series_values(false)
+{
+}
+
+TestD4Sequence::TestD4Sequence(const TestD4Sequence &rhs) : D4Sequence(rhs), TestCommon(rhs)
+{
+    m_duplicate(rhs);
+}
+
+TestD4Sequence::~TestD4Sequence()
+{
+}
+
+TestD4Sequence &
+TestD4Sequence::operator=(const TestD4Sequence &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<D4Sequence &>(*this) = rhs;
+
+    m_duplicate(rhs);
+
+    return *this;
+}
+
+void
+TestD4Sequence::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool
+TestD4Sequence::read()
+{
+    if (read_p())
+        return true;
+
+    if (d_current < d_len) {
+    	for (Vars_iter i = var_begin(), e = var_end(); i != e; ++i)
+            if ((*i)->send_p() || (*i)->is_in_selection())
+                (*i)->read();
+
+    	// Make sure the child member read() methods are called since
+    	// that is how the 'series' values work.
+    	set_read_p(false);
+
+    	++d_current;
+    	return false;
+    }
+    else {
+        return true;                // No more values
+    }
+}
+
+void
+TestD4Sequence::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/TestSequence.h b/tests/TestD4Sequence.h
similarity index 60%
copy from tests/TestSequence.h
copy to tests/TestD4Sequence.h
index 8ac1d0b..b63aac9 100644
--- a/tests/TestSequence.h
+++ b/tests/TestD4Sequence.h
@@ -4,7 +4,7 @@
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
 // Access Protocol.
 
-// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Copyright (c) 2013 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -19,44 +19,34 @@
 // 
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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
+#ifndef _testd4sequence_h
+#define _testd4sequence_h 1
 
-#include "Sequence.h"
+#include "D4Sequence.h"
 #include "TestCommon.h"
 
 using namespace libdap ;
 
-class TestSequence: public Sequence, public TestCommon {
+class TestD4Sequence: public D4Sequence, public TestCommon {
 private:
-    int d_len;
-    int d_current;
+    int d_len; // The number of elements/instances in this sequence
+    int d_current; // Which instance are we currently reading
     bool d_series_values;
     
-    void _duplicate(const TestSequence &ts);
+    void m_duplicate(const TestD4Sequence &ts);
 
 public:
-    TestSequence(const string &n);
-    TestSequence(const string &n, const string &d);
-    TestSequence(const TestSequence &rhs);
+    TestD4Sequence(const string &n);
+    TestD4Sequence(const string &n, const string &d);
+    TestD4Sequence(const TestD4Sequence &rhs);
 
-    virtual ~TestSequence();
+    virtual ~TestD4Sequence();
  
-    TestSequence &operator=(const TestSequence &rhs);
+    TestD4Sequence &operator=(const TestD4Sequence &rhs);
     virtual BaseType *ptr_duplicate();
 
     virtual bool read();
@@ -66,7 +56,7 @@ public:
     void set_series_values(bool);
     bool get_series_values() { return d_series_values; }
 
-    virtual int length();
+    virtual int length() const { return d_len; }
 };
 
 #endif // _testsequence_h
diff --git a/tests/TestFloat32.cc b/tests/TestFloat32.cc
index f0c97ee..57a2a33 100644
--- a/tests/TestFloat32.cc
+++ b/tests/TestFloat32.cc
@@ -118,9 +118,6 @@ TestFloat32::read()
     if (get_series_values()) {
         d_buf += 10.0;
         d_buf = (float)(trunc(10000 * sin(trunc(d_buf))) / 100);
-	/*
-	d_buf -= 0.11 ;
-	*/
     }
     else {
         d_buf = (float)99.999;
diff --git a/tests/TestFunction.cc b/tests/TestFunction.cc
new file mode 100644
index 0000000..7b513aa
--- /dev/null
+++ b/tests/TestFunction.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) 2013 OPeNDAP, Inc.
+// Authors: Nathan Potter <npotter at opendap.org>
+//         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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include <BaseType.h>
+#include <TestFloat64.h>
+#include <TestStr.h>
+#include <TestArray.h>
+
+#include <Error.h>
+#include <DDS.h>
+
+#include <debug.h>
+#include <util.h>
+
+#include "TestFunction.h"
+
+namespace libdap {
+
+/**
+ * @brief scale a scalar or array variable
+ * This does not work for DAP2 Grids; only Array and scalar variables.
+ */
+void
+function_scale(int argc, BaseType * argv[], DDS &, BaseType **btpp)
+{
+    string info =
+    string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
+    "<function name=\"scale\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions\">\n" +
+    "</function>";
+
+    if (argc == 0) {
+        Str *response = new TestStr("info");
+        response->set_value(info);
+        *btpp = response;
+        return;
+    }
+
+    // Check for 2 arguments
+    DBG(cerr << "argc = " << argc << endl);
+    if (argc != 2)
+        throw Error(malformed_expr,"Wrong number of arguments to scale().");
+
+    double m = extract_double_value(argv[1]);
+
+    DBG(cerr << "m: " << m << << endl);
+
+    // Read the data, scale and return the result.
+    BaseType *dest = 0;
+    double *data;
+    if (argv[0]->is_vector_type()) {
+        TestArray &source = static_cast<TestArray&>(*argv[0]);
+        source.read();
+
+        data = extract_double_array(&source);
+        int length = source.length();
+        for (int i = 0; i < length; ++i)
+            data[i] = data[i] * m;
+
+        Array *result = new TestArray(source);
+
+        result->add_var_nocopy(new TestFloat64(source.name()));
+        result->set_value(data, length);
+
+        delete[] data; // set_value copies.
+
+        dest = result;
+    }
+    else if (argv[0]->is_simple_type() && !(argv[0]->type() == dods_str_c || argv[0]->type() == dods_url_c)) {
+    	argv[0]->read();
+        double data = extract_double_value(argv[0]);
+
+        data *= m;
+
+        Float64 *fdest = new TestFloat64(argv[0]->name());
+
+        fdest->set_value(data);
+        dest = fdest;
+    }
+    else {
+        throw Error(malformed_expr,"The scale() function works only for Arrays and scalars.");
+    }
+
+    *btpp = dest;
+    return;
+}
+
+} // namesspace libdap
diff --git a/tests/TestFunction.h b/tests/TestFunction.h
new file mode 100644
index 0000000..d4fba58
--- /dev/null
+++ b/tests/TestFunction.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) 2013 OPeNDAP, Inc.
+// Authors: Nathan Potter <npotter at opendap.org>
+//		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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <ServerFunction.h>
+
+namespace libdap {
+
+class BaseType;
+class DDS;
+
+/**
+ * The scale() function scales data.
+ */
+void function_scale(int argc, BaseType *argv[], DDS &dds, BaseType **btpp) ;
+
+/**
+ * The LinearScaleFunction class encapsulates the linear_scale function 'function_linear_scale'
+ * along with additional meta-data regarding its use and applicability.
+ */
+class TestFunction: public libdap::ServerFunction {
+public:
+	TestFunction()
+    {
+		setName("scale");
+		setDescriptionString("The scale() function is for testing.");
+		setUsageString("scale(var, num): scale var by num. var can be a scalar or an array");
+		setRole("http://services.opendap.org/dap4/server-side-function/scale");
+		setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions");
+		setFunction(libdap::function_scale);
+		setVersion("1.0");
+    }
+    virtual ~TestFunction()
+    {
+    }
+};
+
+} // libdap namespace
diff --git a/tests/TestInt16.cc b/tests/TestInt16.cc
index f8c575e..970a013 100644
--- a/tests/TestInt16.cc
+++ b/tests/TestInt16.cc
@@ -11,18 +11,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
 //
@@ -90,7 +90,7 @@ TestInt16::ptr_duplicate()
     return new TestInt16(*this);
 }
 
-void 
+void
 TestInt16::output_values(std::ostream &out)
 {
     print_val(out, "", false);
@@ -106,13 +106,19 @@ TestInt16::read()
 	sleep(test_variable_sleep_interval);
 
     if (get_series_values()) {
-       d_buf = (short)(16 * d_buf);
+        // Change for OSX 10.9 based on change needed for TestInt32.
+        // jhrg 3/26/14
+        d_buf <<= 4;
+		if (!d_buf)
+			d_buf = 16;
+
+       //d_buf = (short)(16 * d_buf);
     }
     else {
         d_buf = 32000;
     }
 
     set_read_p(true);
-    
+
     return true;
 }
diff --git a/tests/TestInt32.cc b/tests/TestInt32.cc
index f0f8e0d..1f1931b 100644
--- a/tests/TestInt32.cc
+++ b/tests/TestInt32.cc
@@ -11,18 +11,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
 //
@@ -44,7 +44,7 @@
 #include <process.h>
 #endif
 
-//#define DODS_DEBUG 
+//#define DODS_DEBUG
 
 #include "TestInt32.h"
 #include "debug.h"
@@ -92,34 +92,32 @@ TestInt32::ptr_duplicate()
     return new TestInt32(*this);
 }
 
-void 
+void
 TestInt32::output_values(std::ostream &out)
 {
     print_val(out, "", false);
 }
 
-bool
-TestInt32::read()
+bool TestInt32::read()
 {
-    DBG(cerr << "Entering TestInt32::read for " << name() << endl);
-    if (read_p())
-	return true;
+	if (read_p()) return true;
 
-    if (test_variable_sleep_interval > 0)
-	sleep(test_variable_sleep_interval);
+	if (test_variable_sleep_interval > 0) sleep(test_variable_sleep_interval);
 
-    if (get_series_values()) {
-        d_buf = 32 * d_buf;
-        if (!d_buf)
-            d_buf = 32;
-    }
-    else {
-        d_buf = 123456789;
-    }
+	if (get_series_values()) {
+		// This line stopped working when I upgraded the compiler on osx 10.9.
+		// to version Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
+		// jhrg 3/12/14
+		// d_buf = d_buf * 32;
+		d_buf <<= 5;
+		if (!d_buf)
+			d_buf = 32;
+	}
+	else {
+		d_buf = 123456789;
+	}
 
-    set_read_p(true);
+	set_read_p(true);
 
-    DBG(cerr << "In TestInt32::read, _buf = " << d_buf << endl);
-    
-    return true;
+	return true;
 }
diff --git a/tests/TestInt16.cc b/tests/TestInt64.cc
similarity index 61%
copy from tests/TestInt16.cc
copy to tests/TestInt64.cc
index f8c575e..69426d3 100644
--- a/tests/TestInt16.cc
+++ b/tests/TestInt64.cc
@@ -11,32 +11,21 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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
+#ifndef WIN64
 #include <unistd.h>
 #else
 #include <io.h>
@@ -44,61 +33,64 @@
 #include <process.h>
 #endif
 
-#include "TestInt16.h"
+//#define DODS_DEBUG
+
+#include "TestInt64.h"
+#include "debug.h"
 
 extern int test_variable_sleep_interval;
 
 void
-TestInt16::_duplicate(const TestInt16 &ts)
+TestInt64::_duplicate(const TestInt64 &ts)
 {
     d_series_values = ts.d_series_values;
 }
 
-TestInt16::TestInt16(const string &n) : Int16(n), d_series_values(false)
+TestInt64::TestInt64(const string &n) : Int64(n), d_series_values(false)
 {
     d_buf = 1;
 }
 
-TestInt16::TestInt16(const string &n, const string &d)
-    : Int16(n, d), d_series_values(false)
+TestInt64::TestInt64(const string &n, const string &)
+    : Int64(n), d_series_values(false)
 {
     d_buf = 1;
 }
 
-TestInt16::TestInt16(const TestInt16 &rhs) : Int16(rhs), TestCommon(rhs)
+TestInt64::TestInt64(const TestInt64 &rhs) : Int64(rhs), TestCommon(rhs)
 {
     _duplicate(rhs);
 }
 
-TestInt16 &
-TestInt16::operator=(const TestInt16 &rhs)
+TestInt64 &
+TestInt64::operator=(const TestInt64 &rhs)
 {
     if (this == &rhs)
 	return *this;
 
-    dynamic_cast<Int16 &>(*this) = rhs; // run Constructor=
+    dynamic_cast<Int64 &>(*this) = rhs; // run Constructor=
 
     _duplicate(rhs);
 
     return *this;
 }
 
-
 BaseType *
-TestInt16::ptr_duplicate()
+TestInt64::ptr_duplicate()
 {
-    return new TestInt16(*this);
+    return new TestInt64(*this);
 }
 
-void 
-TestInt16::output_values(std::ostream &out)
+void
+TestInt64::output_values(std::ostream &out)
 {
     print_val(out, "", false);
 }
 
 bool
-TestInt16::read()
+TestInt64::read()
 {
+    DBG(cerr << "Entering TestInt64::read for " << name() << endl);
     if (read_p())
 	return true;
 
@@ -106,13 +98,19 @@ TestInt16::read()
 	sleep(test_variable_sleep_interval);
 
     if (get_series_values()) {
-       d_buf = (short)(16 * d_buf);
+    	// was d_buf = 64 * d_buf; but a change in the compiler broke eqiv code in Int32.cc
+    	// jhrg 3/12/14
+    	d_buf <<= 6;
+        if (!d_buf)
+            d_buf = 64;
     }
     else {
-        d_buf = 32000;
+        d_buf = 0x00ffffffffffffff;
     }
 
     set_read_p(true);
-    
+
+    DBG(cerr << "In TestInt64::read, _buf = " << d_buf << endl);
+
     return true;
 }
diff --git a/tests/TestStructure.h b/tests/TestInt64.h
similarity index 58%
copy from tests/TestStructure.h
copy to tests/TestInt64.h
index 526a542..d664937 100644
--- a/tests/TestStructure.h
+++ b/tests/TestInt64.h
@@ -19,49 +19,41 @@
 // 
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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 _testint64_h
+#define _testint64_h 1
 
-#ifndef _teststructure_h
-#define _teststructure_h 1
 
-#include "Structure.h"
+#include "Int64.h"
 #include "TestCommon.h"
 
 using namespace libdap ;
 
-class TestStructure: public Structure, public TestCommon {
+class TestInt64: public Int64, public TestCommon {
     bool d_series_values;
-    void _duplicate(const TestStructure &ts);
+    void _duplicate(const TestInt64 &ts);
 
 public:
-    TestStructure(const string &n);
-    TestStructure(const string &n, const string &d);
-    TestStructure(const TestStructure &rhs);
+    TestInt64(const string &n);
+    TestInt64(const string &n, const string &d);
+    TestInt64(const TestInt64 &rhs);
 
-    virtual ~TestStructure();
+    virtual ~TestInt64() {}
 
-    TestStructure &operator=(const TestStructure &rhs);
+    TestInt64 &operator=(const TestInt64 &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 void set_series_values(bool sv) { d_series_values = sv; }
+    virtual bool get_series_values() { return d_series_values; }
 };
 
-#endif // _teststructure_h
+#endif //_testint64_h
+
diff --git a/tests/TestInt8.cc b/tests/TestInt8.cc
new file mode 100644
index 0000000..7cb8eba
--- /dev/null
+++ b/tests/TestInt8.cc
@@ -0,0 +1,101 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include "TestInt8.h"
+
+extern int test_variable_sleep_interval;
+
+void TestInt8::m_duplicate(const TestInt8 &ts)
+{
+	d_series_values = ts.d_series_values;
+}
+
+TestInt8::TestInt8(const string &n) :
+		Int8(n), d_series_values(false)
+{
+	d_buf = 1;
+}
+
+TestInt8::TestInt8(const string &n, const string &d) :
+		Int8(n, d), d_series_values(false)
+{
+	d_buf = 1;
+}
+
+TestInt8::TestInt8(const TestInt8 &rhs) :
+		Int8(rhs), TestCommon(rhs)
+{
+	m_duplicate(rhs);
+}
+
+TestInt8 &
+TestInt8::operator=(const TestInt8 &rhs)
+{
+	if (this == &rhs) return *this;
+
+	dynamic_cast<Int8 &>(*this) = rhs; // run Constructor=
+
+	m_duplicate(rhs);
+
+	return *this;
+}
+
+BaseType *
+TestInt8::ptr_duplicate()
+{
+	return new TestInt8(*this);
+}
+
+void TestInt8::output_values(std::ostream &out)
+{
+	print_val(out, "", false);
+}
+
+bool TestInt8::read()
+{
+	if (read_p()) return true;
+
+	if (test_variable_sleep_interval > 0) sleep (test_variable_sleep_interval);
+
+	if (get_series_values()) {
+		d_buf = (dods_int8) (2 * d_buf);
+	}
+	else {
+		d_buf = 127;
+	}
+
+	set_read_p(true);
+
+	return true;
+}
diff --git a/tests/TestStructure.h b/tests/TestInt8.h
similarity index 58%
copy from tests/TestStructure.h
copy to tests/TestInt8.h
index 526a542..e8d08ee 100644
--- a/tests/TestStructure.h
+++ b/tests/TestInt8.h
@@ -4,7 +4,7 @@
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
 // Access Protocol.
 
-// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Copyright (c) 2013 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -19,49 +19,42 @@
 // 
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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 _testint8_h
+#define _testint8_h 1
 
-#ifndef _teststructure_h
-#define _teststructure_h 1
 
-#include "Structure.h"
+#include "Int8.h"
 #include "TestCommon.h"
 
 using namespace libdap ;
 
-class TestStructure: public Structure, public TestCommon {
+class TestInt8: public Int8, public TestCommon {
     bool d_series_values;
-    void _duplicate(const TestStructure &ts);
+    void m_duplicate(const TestInt8 &ts);
 
 public:
-    TestStructure(const string &n);
-    TestStructure(const string &n, const string &d);
-    TestStructure(const TestStructure &rhs);
+    TestInt8(const string &n);
+    TestInt8(const string &n, const string &d);
+    TestInt8(const TestInt8 &rhs);
 
-    virtual ~TestStructure();
+    virtual ~TestInt8() {}
 
-    TestStructure &operator=(const TestStructure &rhs);
+    TestInt8 &operator=(const TestInt8 &rhs);
 
     virtual BaseType *ptr_duplicate();
-
+    
     virtual bool read();
     
     virtual void output_values(std::ostream &out);
 
-    void set_series_values(bool);
+    void set_series_values(bool sv) { d_series_values = sv; }
     bool get_series_values() { return d_series_values; }
 };
 
-#endif // _teststructure_h
+#endif // _testint8_h
+
diff --git a/tests/TestSequence.cc b/tests/TestSequence.cc
index 3400b60..80325e7 100644
--- a/tests/TestSequence.cc
+++ b/tests/TestSequence.cc
@@ -1,4 +1,3 @@
-
 // -*- mode: c++; c-basic-offset:4 -*-
 
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
@@ -11,18 +10,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
 //
@@ -35,16 +34,23 @@
 //
 // 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 
+// that contain other sequences. jhrg 2/2/98
 
-#include "TestSequence.h"
-#include "TestCommon.h"
+//#define DODS_DEBUG
 
 #include "config.h"
+#include "D4Group.h"
+#include "Constructor.h"
+#include "D4Sequence.h"
 #include "debug.h"
 
-void
-TestSequence::_duplicate(const TestSequence &ts)
+#include "TestSequence.h"
+#include "TestD4Sequence.h"
+#include "TestCommon.h"
+
+using namespace libdap;
+
+void TestSequence::_duplicate(const TestSequence &ts)
 {
     d_current = ts.d_current;
     d_len = ts.d_len;
@@ -57,17 +63,18 @@ 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) :
+        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 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)
+TestSequence::TestSequence(const TestSequence &rhs) :
+        Sequence(rhs), TestCommon(rhs)
 {
     _duplicate(rhs);
 }
@@ -79,8 +86,7 @@ TestSequence::~TestSequence()
 TestSequence &
 TestSequence::operator=(const TestSequence &rhs)
 {
-    if (this == &rhs)
-	return *this;
+    if (this == &rhs) return *this;
 
     dynamic_cast<Sequence &>(*this) = rhs; // run Constructor=
 
@@ -89,8 +95,21 @@ TestSequence::operator=(const TestSequence &rhs)
     return *this;
 }
 
-void
-TestSequence::output_values(std::ostream &out)
+BaseType *
+TestSequence::transform_to_dap4(D4Group *root, Constructor *container)
+{
+
+    D4Sequence *dest = new TestD4Sequence(name());
+
+    Constructor::transform_to_dap4(root, dest);
+
+    dest->set_length(-1);
+    dest->set_parent(container);
+
+    return dest;
+}
+
+void TestSequence::output_values(std::ostream &out)
 {
     print_val(out, "", false);
 }
@@ -98,28 +117,27 @@ TestSequence::output_values(std::ostream &out)
 // Read values from text files. Sequence instances are stored on separate
 // lines. Line can be no more than 255 characters long.
 
-bool 
-TestSequence::read()
+bool TestSequence::read()
 {
     DBG(cerr << "Entering TestSequence::read for " << name() << endl);
-    
-    if (read_p())
-        return true;
-        
+
+    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);
+        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
+        // jhrg original version from 10/9/13: return false; // No more values
+        return true;
     }
-        
+
     Vars_iter i = var_begin();
     while (i != var_end()) {
         if ((*i)->send_p() || (*i)->is_in_selection()) {
@@ -128,26 +146,24 @@ TestSequence::read()
         }
         ++i;
     }
-    
+
     set_unsent_data(true);
     DBG(cerr << "Leaving TestSequence::read for " << name() << endl);
-    return true;
+    return false;
 }
 
-void
-TestSequence::set_series_values(bool sv)
+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()
+int TestSequence::length() const
 {
     return 5;
 }
diff --git a/tests/TestSequence.h b/tests/TestSequence.h
index 8ac1d0b..b4a60b3 100644
--- a/tests/TestSequence.h
+++ b/tests/TestSequence.h
@@ -11,18 +11,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
 //
@@ -41,12 +41,17 @@
 
 using namespace libdap ;
 
+namespace libdap {
+	class D4Group;
+	class Constructor;
+}
+
 class TestSequence: public Sequence, public TestCommon {
 private:
     int d_len;
     int d_current;
     bool d_series_values;
-    
+
     void _duplicate(const TestSequence &ts);
 
 public:
@@ -55,18 +60,19 @@ public:
     TestSequence(const TestSequence &rhs);
 
     virtual ~TestSequence();
- 
+
     TestSequence &operator=(const TestSequence &rhs);
     virtual BaseType *ptr_duplicate();
+    BaseType * transform_to_dap4(libdap::D4Group *root, libdap::Constructor *container);
 
     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();
+    virtual int length() const;
 };
 
 #endif // _testsequence_h
diff --git a/tests/TestStr.cc b/tests/TestStr.cc
index bfca5b0..ea99c6c 100644
--- a/tests/TestStr.cc
+++ b/tests/TestStr.cc
@@ -11,18 +11,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
 //
@@ -91,27 +91,29 @@ TestStr::ptr_duplicate()
     return new TestStr(*this);
 }
 
-void 
+void
 TestStr::output_values(std::ostream &out)
 {
     print_val(out, "", false);
 }
 
-bool
-TestStr::read()
+bool TestStr::read()
 {
-    static int count = 0;
-    
-    if (read_p())
-	return true;
+	static int count = 0;
+
+	if (read_p()) return true;
 
-    if (test_variable_sleep_interval > 0)
-	sleep(test_variable_sleep_interval);
+	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);
+	string dods_str_test;
+	if (get_series_values())
+	    dods_str_test = "Silly test string: " + long_to_string(++count);
+	else
+	    dods_str_test = "Silly test string: 1";
 
-    set_read_p(true);
+	(void) val2buf(&dods_str_test);
 
-    return true;
+	set_read_p(true);
+
+	return true;
 }
diff --git a/tests/TestStructure.cc b/tests/TestStructure.cc
index 2b5300d..666b5c0 100644
--- a/tests/TestStructure.cc
+++ b/tests/TestStructure.cc
@@ -1,4 +1,3 @@
-
 // -*- mode: c++; c-basic-offset:4 -*-
 
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
@@ -36,46 +35,50 @@
 //#define DODS_DEBUG
 
 #include "config.h"
-#include "TestStructure.h"
+#include "D4Group.h"
+#include "Constructor.h"
 #include "debug.h"
 
-void
-TestStructure::_duplicate(const TestStructure &ts)
+#include "TestStructure.h"
+
+using namespace libdap;
+
+void TestStructure::m_duplicate(const TestStructure &ts)
 {
-    d_series_values = ts.d_series_values;
+	d_series_values = ts.d_series_values;
 }
 
 BaseType *
 TestStructure::ptr_duplicate()
 {
-    return new TestStructure(*this);
+	return new TestStructure(*this);
 }
 
-TestStructure::TestStructure(const TestStructure &rhs) : Structure(rhs), TestCommon(rhs)
+TestStructure::TestStructure(const TestStructure &rhs) :
+		Structure(rhs), TestCommon(rhs)
 {
-    _duplicate(rhs);
+	m_duplicate(rhs);
 }
 
 TestStructure &
 TestStructure::operator=(const TestStructure &rhs)
 {
-    if (this == &rhs)
-	return *this;
+	if (this == &rhs) return *this;
 
-    dynamic_cast<Structure &>(*this) = rhs; // run Constructor=
+	dynamic_cast<Structure &>(*this) = rhs; // run Constructor=
 
-    _duplicate(rhs);
+	m_duplicate(rhs);
 
-    return *this;
+	return *this;
 }
 
-TestStructure::TestStructure(const string &n) : Structure(n),
-        d_series_values(false)
+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(const string &n, const string &d) :
+		Structure(n, d), d_series_values(false)
 {
 }
 
@@ -83,68 +86,73 @@ TestStructure::~TestStructure()
 {
 }
 
-void
-TestStructure::output_values(std::ostream &out)
+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 << " }" ;
+	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 << " }";
+}
+
+BaseType *
+TestStructure::transform_to_dap4(D4Group *root, Constructor *container)
+{
+	Structure *dest = new TestStructure(name(), dataset());
+
+	Constructor::transform_to_dap4(root, dest);
+	dest->set_parent(container);
+
+	return dest;
 }
 
 // For this `Test' class, run the read mfunc for each of variables which
 // comprise the structure.
 
-bool
-TestStructure::read()
+bool TestStructure::read()
 {
-    if (read_p())
-	return true;
+	if (read_p()) return true;
 
-    for (Vars_iter i = var_begin(); i != var_end(); i++)
-    {
-	if (!(*i)->read())
-	{
-	    return false;
+	for (Vars_iter i = var_begin(); i != var_end(); i++) {
+		if (!(*i)->read()) {
+			return false;
+		}
 	}
-    }
 
-    set_read_p(true);
+	set_read_p(true);
 
-    return true;
+	return true;
 }
 
-void
-TestStructure::set_series_values(bool sv)
+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;
-    }
+	Vars_iter i = var_begin();
+	while (i != var_end()) {
+		dynamic_cast<TestCommon&>(*(*i)).set_series_values(sv);
+		++i;
+	}
 
-    d_series_values = sv;
+	d_series_values = sv;
 }
diff --git a/tests/TestStructure.h b/tests/TestStructure.h
index 526a542..bdcfe75 100644
--- a/tests/TestStructure.h
+++ b/tests/TestStructure.h
@@ -11,18 +11,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
 //
@@ -41,9 +41,14 @@
 
 using namespace libdap ;
 
+namespace libdap {
+	class D4Group;
+	class Constructor;
+}
+
 class TestStructure: public Structure, public TestCommon {
     bool d_series_values;
-    void _duplicate(const TestStructure &ts);
+    void m_duplicate(const TestStructure &ts);
 
 public:
     TestStructure(const string &n);
@@ -55,9 +60,10 @@ public:
     TestStructure &operator=(const TestStructure &rhs);
 
     virtual BaseType *ptr_duplicate();
+    BaseType *transform_to_dap4(libdap::D4Group *root, libdap::Constructor *container);
 
     virtual bool read();
-    
+
     virtual void output_values(std::ostream &out);
 
     void set_series_values(bool);
diff --git a/tests/TestUInt16.cc b/tests/TestUInt16.cc
index fbc5d97..63b68e0 100644
--- a/tests/TestUInt16.cc
+++ b/tests/TestUInt16.cc
@@ -11,18 +11,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
 //
@@ -91,7 +91,7 @@ TestUInt16::ptr_duplicate()
     return new TestUInt16(*this);
 }
 
-void 
+void
 TestUInt16::output_values(std::ostream &out)
 {
     print_val(out, "", false);
@@ -107,13 +107,19 @@ TestUInt16::read()
 	sleep(test_variable_sleep_interval);
 
     if (get_series_values()) {
-        d_buf = (short)(16 * d_buf);
+        // Change for OSX 10.9 based on change needed for TestInt32.
+        // jhrg 3/26/14
+        d_buf <<= 4;
+		if (!d_buf)
+			d_buf = 16;
+
+        // d_buf = (short)(16 * d_buf);
     }
     else {
         d_buf = 64000;
     }
-    
+
     set_read_p(true);
-    
+
     return true;
 }
diff --git a/tests/TestUInt32.cc b/tests/TestUInt32.cc
index faea396..8b7af18 100644
--- a/tests/TestUInt32.cc
+++ b/tests/TestUInt32.cc
@@ -11,18 +11,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
 //
@@ -91,7 +91,7 @@ TestUInt32::ptr_duplicate()
     return new TestUInt32(*this);
 }
 
-void 
+void
 TestUInt32::output_values(std::ostream &out)
 {
     print_val(out, "", false);
@@ -107,13 +107,19 @@ TestUInt32::read()
 	sleep(test_variable_sleep_interval);
 
     if (get_series_values()) {
-        d_buf = 32 * d_buf;
+   		// This line stopped working when I upgraded the compiler on osx 10.9.
+		// to version Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
+		// jhrg 3/12/14
+		// d_buf = d_buf * 32;
+		d_buf <<= 5;
+		if (!d_buf)
+			d_buf = 32;
     }
     else {
         d_buf = 0xf0000000;		// about 4 billion
     }
 
     set_read_p(true);
-    
+
     return true;
 }
diff --git a/tests/TestUInt16.cc b/tests/TestUInt64.cc
similarity index 63%
copy from tests/TestUInt16.cc
copy to tests/TestUInt64.cc
index fbc5d97..429fff3 100644
--- a/tests/TestUInt16.cc
+++ b/tests/TestUInt64.cc
@@ -19,24 +19,13 @@
 // 
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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
+#ifndef WIN64
 #include <unistd.h>
 #else
 #include <io.h>
@@ -44,40 +33,40 @@
 #include <process.h>
 #endif
 
-#include "TestUInt16.h"
+#include "TestUInt64.h"
 
 extern int test_variable_sleep_interval;
 
 void
-TestUInt16::_duplicate(const TestUInt16 &ts)
+TestUInt64::_duplicate(const TestUInt64 &ts)
 {
     d_series_values = ts.d_series_values;
 }
 
 
-TestUInt16::TestUInt16(const string &n) : UInt16(n), d_series_values(false)
+TestUInt64::TestUInt64(const string &n) : UInt64(n), d_series_values(false)
 {
     d_buf = 1;
 }
 
-TestUInt16::TestUInt16(const string &n, const string &d)
-    : UInt16(n, d), d_series_values(false)
+TestUInt64::TestUInt64(const string &n, const string &d)
+    : UInt64(n, d), d_series_values(false)
 {
     d_buf = 1;
 }
 
-TestUInt16::TestUInt16(const TestUInt16 &rhs) : UInt16(rhs), TestCommon(rhs)
+TestUInt64::TestUInt64(const TestUInt64 &rhs) : UInt64(rhs), TestCommon(rhs)
 {
     _duplicate(rhs);
 }
 
-TestUInt16 &
-TestUInt16::operator=(const TestUInt16 &rhs)
+TestUInt64 &
+TestUInt64::operator=(const TestUInt64 &rhs)
 {
     if (this == &rhs)
 	return *this;
 
-    dynamic_cast<UInt16 &>(*this) = rhs; // run Constructor=
+    dynamic_cast<UInt64 &>(*this) = rhs; // run Constructor=
 
     _duplicate(rhs);
 
@@ -86,19 +75,19 @@ TestUInt16::operator=(const TestUInt16 &rhs)
 
 
 BaseType *
-TestUInt16::ptr_duplicate()
+TestUInt64::ptr_duplicate()
 {
-    return new TestUInt16(*this);
+    return new TestUInt64(*this);
 }
 
 void 
-TestUInt16::output_values(std::ostream &out)
+TestUInt64::output_values(std::ostream &out)
 {
     print_val(out, "", false);
 }
 
 bool
-TestUInt16::read()
+TestUInt64::read()
 {
     if (read_p())
 	return true;
@@ -107,12 +96,12 @@ TestUInt16::read()
 	sleep(test_variable_sleep_interval);
 
     if (get_series_values()) {
-        d_buf = (short)(16 * d_buf);
+        d_buf = 64 * d_buf;
     }
     else {
-        d_buf = 64000;
+        d_buf = 0xffffffffffffffff;		// really big
     }
-    
+
     set_read_p(true);
     
     return true;
diff --git a/tests/TestStructure.h b/tests/TestUInt64.h
similarity index 60%
copy from tests/TestStructure.h
copy to tests/TestUInt64.h
index 526a542..fee5fee 100644
--- a/tests/TestStructure.h
+++ b/tests/TestUInt64.h
@@ -19,49 +19,41 @@
 // 
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 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 _testuint64_h
+#define _testuint64_h 1
 
-#ifndef _teststructure_h
-#define _teststructure_h 1
 
-#include "Structure.h"
+#include "UInt64.h"
 #include "TestCommon.h"
 
 using namespace libdap ;
 
-class TestStructure: public Structure, public TestCommon {
+class TestUInt64: public UInt64, public TestCommon {
     bool d_series_values;
-    void _duplicate(const TestStructure &ts);
+    void _duplicate(const TestUInt64 &ts);
 
 public:
-    TestStructure(const string &n);
-    TestStructure(const string &n, const string &d);
-    TestStructure(const TestStructure &rhs);
+    TestUInt64(const string &n);
+    TestUInt64(const string &n, const string &d);
+    TestUInt64(const TestUInt64 &rhs);
 
-    virtual ~TestStructure();
+    virtual ~TestUInt64() {}
 
-    TestStructure &operator=(const TestStructure &rhs);
+    TestUInt64 &operator=(const TestUInt64 &rhs);
 
     virtual BaseType *ptr_duplicate();
-
+    
     virtual bool read();
     
     virtual void output_values(std::ostream &out);
 
-    void set_series_values(bool);
+    void set_series_values(bool sv) { d_series_values = sv; }
     bool get_series_values() { return d_series_values; }
 };
 
-#endif // _teststructure_h
+#endif // _testuint64_h
+
diff --git a/tests/atconfig b/tests/atconfig
index d16bf52..3e63a74 100644
--- a/tests/atconfig
+++ b/tests/atconfig
@@ -4,13 +4,13 @@
 
 # The test suite will define top_srcdir=/../.. etc.
 at_testdir='tests'
-abs_builddir='/home/jimg/src/hyrax_1.9_release/src/libdap/tests'
+abs_builddir='/Users/jimg/src/opendap/hyrax_git/libdap4/tests'
 at_srcdir='.'
-abs_srcdir='/home/jimg/src/hyrax_1.9_release/src/libdap/tests'
+abs_srcdir='/Users/jimg/src/opendap/hyrax_git/libdap4/tests'
 at_top_srcdir='..'
-abs_top_srcdir='/home/jimg/src/hyrax_1.9_release/src/libdap'
+abs_top_srcdir='/Users/jimg/src/opendap/hyrax_git/libdap4'
 at_top_build_prefix='../'
-abs_top_builddir='/home/jimg/src/hyrax_1.9_release/src/libdap'
+abs_top_builddir='/Users/jimg/src/opendap/hyrax_git/libdap4'
 
 # Backward compatibility with Autotest <= 2.59b:
 at_top_builddir=$at_top_build_prefix
diff --git a/tests/dds-test.cc b/tests/dds-test.cc
index c658b98..d34f61a 100644
--- a/tests/dds-test.cc
+++ b/tests/dds-test.cc
@@ -46,17 +46,21 @@
 #include "util.h"
 #include "Error.h"
 
+#if 0
 #ifdef DAP4
 #include "D4ParserSax2.h"
 #include "D4BaseTypeFactory.h"
 #endif
+#endif
 
 using namespace libdap;
 
 void test_scanner();
 void test_parser(const string &name);
 void test_class();
+#if 0
 void test_dap4_parser(const string &name);
+#endif
 
 int ddslex();
 // int ddsparse(DDS &);
@@ -68,18 +72,30 @@ static bool print_ddx = false;
 const char *prompt = "dds-test: ";
 
 void usage(string name) {
+    cerr << "Usage: " << name << "[s] [pd] [c]" << endl
+            << "s: Test the scanner." << endl
+            << "p: Test the parser; reads from stdin and prints the" << endl
+            << "   internal structure to stdout." << endl
+            << "d: Turn on parser debugging. (only for the hard core.)" << endl
+            << "c: Test the C++ code for manipulating DDS objects." << endl
+            << "   Reads from stdin, parses and writes the modified DDS" << endl
+            << "   to stdout." << endl;
+#if 0
     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.");
+#endif
 }
 
 int main(int argc, char *argv[]) {
-    GetOpt getopt(argc, argv, "spP:dfF:cx");
+    GetOpt getopt(argc, argv, "spP:dcx"); // remove fF:
     int option_char;
     int scanner_test = 0, parser_test = 0, class_test = 0;
+#if 0
     int dap4_parser_test = 0;
+#endif
     string name = "";
     // process options
 
@@ -98,7 +114,7 @@ int main(int argc, char *argv[]) {
             parser_test = 1;
             name = getopt.optarg;
             break;
-
+#if 0
         case 'f':
             dap4_parser_test = 1;
             break;
@@ -107,7 +123,7 @@ int main(int argc, char *argv[]) {
             dap4_parser_test = 1;
             name = getopt.optarg;
             break;
-
+#endif
         case 'x':
             print_ddx = true;
             break;
@@ -120,7 +136,7 @@ int main(int argc, char *argv[]) {
             return 1;
         }
 
-    if (!scanner_test && !parser_test && !class_test && !dap4_parser_test) {
+    if (!scanner_test && !parser_test && !class_test/* && !dap4_parser_test*/) {
         usage(argv[0]);
         return 1;
     }
@@ -131,10 +147,10 @@ int main(int argc, char *argv[]) {
 
         if (parser_test)
             test_parser(name);
-
+#if 0
         if (dap4_parser_test)
             test_dap4_parser(name);
-
+#endif
         if (class_test)
             test_class();
     }
@@ -254,7 +270,8 @@ void test_parser(const string &name) {
     factory = 0;
 }
 
-void test_dap4_parser(const string &/*name*/) {
+#if 0
+void test_dap4_parser(const string &name) {
 #ifdef DAP4
     D4BaseTypeFactory factory;
 
@@ -286,6 +303,7 @@ void test_dap4_parser(const string &/*name*/) {
     cerr << "DAP4 parsing not supported by this version of libdap" << endl;
 #endif
 }
+#endif
 
 void test_class(void) {
     BaseTypeFactory *factory = new BaseTypeFactory;
diff --git a/tests/dmr-test.cc b/tests/dmr-test.cc
new file mode 100644
index 0000000..9c467c0
--- /dev/null
+++ b/tests/dmr-test.cc
@@ -0,0 +1,476 @@
+// -*- 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,2013 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.
+
+// Test the DMR parser
+
+#include "config.h"
+
+#include <stdint.h>
+#include <cstring>
+
+#include <fstream>
+#include <memory>
+
+#include "crc.h"
+
+#include <GetOpt.h>
+
+#include "BaseType.h"
+#include "Array.h"
+#include "D4Enum.h"
+
+#include "DMR.h"
+#include "D4Group.h"
+#include "D4StreamUnMarshaller.h"
+#include "chunked_ostream.h"
+#include "chunked_istream.h"
+
+#include "util.h"
+#include "InternalErr.h"
+#include "Error.h"
+
+#include "D4ResponseBuilder.h"
+#include "ConstraintEvaluator.h"
+
+#include "D4ParserSax2.h"
+#include "D4TestTypeFactory.h"
+#include "TestCommon.h"
+
+#include "D4ConstraintEvaluator.h"
+#include "D4FunctionEvaluator.h"
+#include "ServerFunctionsList.h"
+#include "D4TestFunction.h"
+#include "D4RValue.h"
+
+#include "util.h"
+#include "mime_util.h"
+#include "debug.h"
+
+int test_variable_sleep_interval = 0;   // Used in Test* classes for testing timeouts.
+
+using namespace libdap;
+
+/**
+ * Open the named XML file and parse it, assuming that it contains a DMR.
+ * @param name The name of the DMR XML file (or '-' for stdin)
+ * @param debug True if the debug mode of the parse should be used
+ * @param print Once parsed, should the DMR object be printed?
+ * @return true if the parse worked, false otherwise
+ */
+DMR *
+test_dap4_parser(const string &name, bool debug, bool print)
+{
+    D4TestTypeFactory *factory = new D4TestTypeFactory;
+    DMR *dataset = new DMR(factory, path_to_filename(name));
+
+    try {
+        D4ParserSax2 parser;
+        if (name == "-") {
+            parser.intern(cin, dataset, debug);
+        }
+        else {
+            fstream in(name.c_str(), ios_base::in);
+            parser.intern(in, dataset, debug);
+        }
+    }
+    catch(...) {
+        delete factory;
+        delete dataset;
+        throw;
+    }
+
+    cout << "Parse successful" << endl;
+
+    if (print) {
+        XMLWriter xml("    ");
+        dataset->print_dap4(xml, false);
+        cout << xml.get_doc() << endl;
+    }
+
+    return dataset;
+}
+
+/**
+ * Should the changing values - meant to mimic the DTS - be used?
+ * @param dmr Set for this DMR
+ * @param state True to use the DTS-like values, false otherwise
+ */
+void
+set_series_values(DMR *dmr, bool state)
+{
+	if (state == true)
+		dmr->root()->set_read_p(false);
+
+	TestCommon *tc = dynamic_cast<TestCommon*>(dmr->root());
+	if (tc)
+		tc->set_series_values(state);
+	else
+		cerr << "Could not cast root group to TestCommon (" << dmr->root()->type_name() << ", " << dmr->root()->name() << ")" << endl;
+}
+
+/**
+ * Call the parser and then serialize the resulting DMR after applying the
+ * constraint. The persistent representation is written to a file. The file
+ * is name '<name>_data.bin'.
+ *
+ * @param dataset
+ * @param constraint
+ * @param series_values
+ * @return The name of the file that hods the response.
+ */
+string
+send_data(DMR *dataset, const string &constraint, const string &function, bool series_values, bool ce_parser_debug)
+{
+    set_series_values(dataset, series_values);
+
+    // This will be used by the DMR that holds the results of running the functions.
+    // It's declared at this scope because we (may) need it for the code beyond the
+    // function parse/eval code that immediately follows. jhrg 3/12/14
+    D4TestTypeFactory d4_factory;
+    auto_ptr<DMR> function_result(new DMR(&d4_factory, "function_results"));
+
+	// The Function Parser
+	if (!function.empty()) {
+		ServerFunctionsList *sf_list = ServerFunctionsList::TheList();
+		ServerFunction *scale = new D4TestFunction;
+		sf_list->add_function(scale);
+
+		D4FunctionEvaluator parser(dataset, sf_list);
+		if (ce_parser_debug) parser.set_trace_parsing(true);
+		bool parse_ok = parser.parse(function);
+		if (!parse_ok)
+			Error("Function Expression failed to parse.");
+		else {
+			if (ce_parser_debug) cerr << "Function Parse OK" << endl;
+
+			parser.eval(function_result.get());
+
+			// Now use the results of running the functions for the remainder of the
+			// send_data operation.
+			dataset = function_result.release();
+		}
+	}
+
+    D4ResponseBuilder rb;
+    rb.set_dataset_name(dataset->name());
+
+    string file_name = dataset->name() + "_data.bin";
+    ofstream out(file_name.c_str(), ios::out|ios::trunc|ios::binary);
+
+	if (!constraint.empty()) {
+		D4ConstraintEvaluator parser(dataset);
+		if (ce_parser_debug)
+		    parser.set_trace_parsing(true);
+		bool parse_ok = parser.parse(constraint);
+		if (!parse_ok)
+			throw Error("Constraint Expression failed to parse.");
+		else if (ce_parser_debug)
+		    cerr << "CE Parse OK" << endl;
+	}
+    else {
+    	dataset->root()->set_send_p(true);
+    }
+
+    rb.send_dap(out, *dataset, /*with mime headers*/ true, !constraint.empty());
+    out.close();
+
+    return file_name;
+}
+
+void
+intern_data(DMR *dataset, /*const string &constraint,*/ bool series_values)
+{
+    set_series_values(dataset, series_values);
+
+    // Mark all variables to be sent in their entirety. No CEs are used
+    // when 'interning' variables' data.
+    dataset->root()->set_send_p(true);
+
+    Crc32 checksum;
+
+    dataset->root()->intern_data(checksum/*, *dataset, eval*/);
+}
+
+DMR *
+read_data_plain(const string &file_name, bool debug)
+{
+    D4BaseTypeFactory *factory = new D4BaseTypeFactory;
+    DMR *dmr = new DMR(factory, "Test_data");
+
+    fstream in(file_name.c_str(), ios::in|ios::binary);
+
+    // Gobble up the response's initial set of MIME headers. Normally
+    // a client would extract information from these headers.
+    remove_mime_header(in);
+
+    chunked_istream cis(in, CHUNK_SIZE);
+
+    // parse the DMR, stopping when the boundary is found.
+    try {
+        // force chunk read
+        // get chunk size
+        int chunk_size = cis.read_next_chunk();
+        // get chunk
+        char chunk[chunk_size];
+        cis.read(chunk, chunk_size);
+        // parse char * with given size
+    	D4ParserSax2 parser;
+    	// '-2' to discard the CRLF pair
+        parser.intern(chunk, chunk_size-2, dmr, debug);
+    }
+    catch(Error &e) {
+    	delete factory;
+    	delete dmr;
+    	cerr << "Exception: " << e.get_error_message() << endl;
+    	return 0;
+    }
+    catch(std::exception &e) {
+    	delete factory;
+    	delete dmr;
+    	cerr << "Exception: " << e.what() << endl;
+    	return 0;
+    }
+    catch(...) {
+    	delete factory;
+    	delete dmr;
+    	cerr << "Exception: unknown error" << endl;
+    	return 0;
+    }
+
+    D4StreamUnMarshaller um(cis, cis.twiddle_bytes());
+
+    dmr->root()->deserialize(um, *dmr);
+
+    return dmr;
+}
+
+static void usage()
+{
+    cerr << "Usage: dmr-test -p|s|t|i <file> [-c <expr>] [-f <function expression>] [-d -x -e]" << endl
+            << "p: Parse a file (use \"-\" for stdin; if a ce or a function is passed those are parsed too)" << endl
+            << "s: Send: parse and then 'send' a response to a file" << endl
+            << "t: Transmit: parse, send and then read the response file" << endl
+            << "i: Intern values (ce and function will be ignored by this)" << endl
+            << "c: Constraint expression " << endl
+            << "f: Function expression" << endl
+            << "d: turn on detailed xml parser debugging" << endl
+            << "D: turn on detailed ce parser debugging" << endl
+            << "x: print the binary object(s) built by the parse, send, trans or intern operations." << endl
+            << "e: use sEries values." << endl;
+}
+
+int
+main(int argc, char *argv[])
+{
+    GetOpt getopt(argc, argv, "p:s:t:i:c:f:xdDeh?");
+    int option_char;
+    bool parse = false;
+    bool debug = false;
+    bool print = false;
+    bool send = false;
+    bool trans = false;
+    bool intern = false;
+    bool series_values = false;
+    bool constrained = false;
+    bool functional = false;
+    bool ce_parser_debug = false;
+    string name = "";
+    string ce = "";
+    string function = "";
+
+    // process options
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'p':
+            parse = true;
+            name = getopt.optarg;
+            break;
+
+        case 's':
+        	send = true;
+        	name = getopt.optarg;
+        	break;
+
+        case 't':
+        	trans = true;
+        	name = getopt.optarg;
+        	break;
+
+        case 'i':
+        	intern = true;
+        	name = getopt.optarg;
+        	break;
+
+        case 'c':
+        	constrained = true;
+        	ce = getopt.optarg;
+        	break;
+
+        case 'f':
+        	functional = true;
+        	function = getopt.optarg;
+        	break;
+
+        case 'd':
+            debug = true;
+            break;
+
+        case 'D':
+            ce_parser_debug = true;
+            break;
+
+        case 'x':
+            print = true;
+            break;
+
+        case 'e':
+        	series_values = true;
+        	break;
+
+        case '?':
+        case 'h':
+            usage();
+            return 0;
+
+        default:
+            cerr << "Error: ";
+            usage();
+            return 1;
+        }
+
+    if (! (parse || send || trans || intern)) {
+        cerr << "Error: ";
+        usage();
+        return 1;
+    }
+
+    try {
+		if (parse) {
+			DMR *dmr = test_dap4_parser(name, debug, print);
+
+			// The CE Parser
+			if (!ce.empty()) {
+				try {
+					D4ConstraintEvaluator parser(dmr);
+					if (ce_parser_debug) parser.set_trace_parsing(true);
+					bool parse_ok = parser.parse(ce);
+					if (!parse_ok)
+						cout << "CE Parse Failed" << endl;
+					else
+						cout << "CE Parse OK" << endl;
+				}
+				catch (Error &e) {
+					cerr << "CE Parse error: " << e.get_error_message() << endl;
+				}
+				catch (...) {
+					cerr << "Ce Parse error: Unknown exception thrown by parser" << endl;
+				}
+			}
+
+			// The Function Parser
+			if (!function.empty()) {
+				try {
+					ServerFunctionsList *sf_list = ServerFunctionsList::TheList();
+				    ServerFunction *scale = new D4TestFunction;
+				    sf_list->add_function(scale);
+
+					D4FunctionEvaluator parser(dmr, sf_list);
+					if (ce_parser_debug) parser.set_trace_parsing(true);
+					bool parse_ok = parser.parse(function);
+					if (!parse_ok)
+						cout << "Function Parse Failed" << endl;
+					else
+						cout << "Function Parse OK" << endl;
+				}
+				catch (Error &e) {
+					cerr << "Function Parse error: " << e.get_error_message() << endl;
+				}
+				catch (...) {
+					cerr << "Function Parse error: Unknown exception thrown by parser" << endl;
+				}
+			}
+
+			delete dmr;
+		}
+
+		if (send) {
+        	DMR *dmr = test_dap4_parser(name, debug, print);
+
+        	string file_name = send_data(dmr, ce, function, series_values, ce_parser_debug);
+        	if (print)
+        		cout << "Response file: " << file_name << endl;
+        	delete dmr;
+        }
+
+        if (trans) {
+        	DMR *dmr = test_dap4_parser(name, debug, print);
+        	string file_name = send_data(dmr, ce, function, series_values, ce_parser_debug);
+         	delete dmr;
+
+        	DMR *client = read_data_plain(file_name, debug);
+
+        	if (print) {
+        		XMLWriter xml;
+        		// received data never have send_p set; don't set 'constrained'
+        		client->print_dap4(xml, false /* constrained */);
+        		cout << xml.get_doc() << endl;
+
+				cout << "The data:" << endl;
+        	}
+
+        	// if trans is used, the data are printed regardless of print's value
+    		client->root()->print_val(cout, "", false);
+    		cout << endl;
+
+        	delete client;
+        }
+
+        if (intern) {
+        	DMR *dmr = test_dap4_parser(name, debug, print);
+        	intern_data(dmr, /*ce,*/ series_values);
+
+        	if (print) {
+        		XMLWriter xml;
+        		dmr->print_dap4(xml, false /*constrained*/);
+        		cout << xml.get_doc() << endl;
+
+				cout << "The data:" << endl;
+        	}
+
+        	// if trans is used, the data are printed regardless of print's value
+    		dmr->root()->print_val(cout, /*space*/"", false);
+    		cout << endl;
+
+        	delete dmr;
+        }
+    }
+    catch (Error &e) {
+        cerr << "Error: " << e.get_error_message() << endl;
+        return 1;
+    }
+
+    return 0;
+}
+
diff --git a/tests/dmr-testsuite/test_array_1.xml b/tests/dmr-testsuite/test_array_1.xml
new file mode 100644
index 0000000..73c838d
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- First in a series of very simple tests. jhrg 7/10/12 -->
+
+<Dataset name="test_array_1" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_1.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <dap:Int32 name="x">
+    <Dim size="5"/>
+  </dap:Int32>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_1.xml.1.func_base b/tests/dmr-testsuite/test_array_1.xml.1.func_base
new file mode 100644
index 0000000..7d4706a
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.1.func_base
@@ -0,0 +1,20 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>09dc38cc</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {123456789, 123456789, 123456789, 123456789, 123456789} }
diff --git a/tests/dmr-testsuite/test_array_1.xml.2.func_base b/tests/dmr-testsuite/test_array_1.xml.2.func_base
new file mode 100644
index 0000000..f287f4c
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.2.func_base
@@ -0,0 +1,20 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>098e5a83</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {1234567890, 1234567890, 1234567890, 1234567890, 1234567890} }
diff --git a/tests/dmr-testsuite/test_array_1.xml.3.func_base b/tests/dmr-testsuite/test_array_1.xml.3.func_base
new file mode 100644
index 0000000..107ddcf
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.3.func_base
@@ -0,0 +1,20 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>ed282162</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {-1234567890, -1234567890, -1234567890, -1234567890, -1234567890} }
diff --git a/tests/dmr-testsuite/test_array_1.xml.4.func_base b/tests/dmr-testsuite/test_array_1.xml.4.func_base
new file mode 100644
index 0000000..c342554
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.4.func_base
@@ -0,0 +1,20 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>73c874c1</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {123456.789, 123456.789, 123456.789, 123456.789, 123456.789} }
diff --git a/tests/dmr-testsuite/test_array_1.xml.5.func_base b/tests/dmr-testsuite/test_array_1.xml.5.func_base
new file mode 100644
index 0000000..2eeef51
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.5.func_base
@@ -0,0 +1,20 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>976e0f20</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {-123456.789, -123456.789, -123456.789, -123456.789, -123456.789} }
diff --git a/tests/dmr-testsuite/test_array_1.xml.6.func_base b/tests/dmr-testsuite/test_array_1.xml.6.func_base
new file mode 100644
index 0000000..c1e4d4c
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.6.func_base
@@ -0,0 +1,20 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>cc090e5b</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {1.13868789542248e+27, 1.13868789542248e+27, 1.13868789542248e+27, 1.13868789542248e+27, 1.13868789542248e+27} }
diff --git a/tests/dmr-testsuite/test_array_1.xml.7.func_base b/tests/dmr-testsuite/test_array_1.xml.7.func_base
new file mode 100644
index 0000000..ef377ad
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.7.func_base
@@ -0,0 +1,20 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>cb1dffcf</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {1.28102388235029e+27, 1.28102388235029e+27, 1.28102388235029e+27, 1.28102388235029e+27, 1.28102388235029e+27} }
diff --git a/tests/dmr-testsuite/test_array_1.xml.baseline b/tests/dmr-testsuite/test_array_1.xml.baseline
new file mode 100644
index 0000000..999caa0
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.baseline
@@ -0,0 +1,8 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_1.xml.send_base b/tests/dmr-testsuite/test_array_1.xml.send_base
new file mode 100644
index 0000000..c48d312
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.send_base
@@ -0,0 +1,9 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
+Response file: test_array_1_data.bin
diff --git a/tests/dmr-testsuite/test_array_1.xml.trans_base b/tests/dmr-testsuite/test_array_1.xml.trans_base
new file mode 100644
index 0000000..3e3534c
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_1.xml.trans_base
@@ -0,0 +1,20 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_1">
+    <Int32 name="x">
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>33fc3688</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ {123456789, 123456789, 123456789, 123456789, 123456789} }
diff --git a/tests/dmr-testsuite/test_array_10.xml b/tests/dmr-testsuite/test_array_10.xml
new file mode 100644
index 0000000..8c8a165
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_10.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+  xml:base="file:test_simple_11.xml"    
+  name="test_simple_11"
+  dapVersion="4.0"
+  dmrVersion="1.0">
+  <Dimension name="d1" size="5"/>
+  <Dimension name="d2" size="3"/>
+  
+  <Opaque name="o">
+    <Dim name="d1"/>
+  </Opaque>
+  
+  <Opaque name="p">
+    <Dim name="d1"/>
+    <Dim name="d2"/>
+  </Opaque>
+  
+</Dataset>   
diff --git a/tests/dmr-testsuite/test_array_10.xml.baseline b/tests/dmr-testsuite/test_array_10.xml.baseline
new file mode 100644
index 0000000..68f10a1
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_10.xml.baseline
@@ -0,0 +1,14 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:test_simple_11.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_11">
+    <Dimension name="d1" size="5"/>
+    <Dimension name="d2" size="3"/>
+    <Opaque name="o">
+        <Dim name="/d1"/>
+    </Opaque>
+    <Opaque name="p">
+        <Dim name="/d1"/>
+        <Dim name="/d2"/>
+    </Opaque>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_10.xml.trans_base b/tests/dmr-testsuite/test_array_10.xml.trans_base
new file mode 100644
index 0000000..cbd7697
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_10.xml.trans_base
@@ -0,0 +1,35 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:test_simple_11.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_11">
+    <Dimension name="d1" size="5"/>
+    <Dimension name="d2" size="3"/>
+    <Opaque name="o">
+        <Dim name="/d1"/>
+    </Opaque>
+    <Opaque name="p">
+        <Dim name="/d1"/>
+        <Dim name="/d2"/>
+    </Opaque>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:test_simple_11.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_11">
+    <Dimension name="d1" size="5"/>
+    <Dimension name="d2" size="3"/>
+    <Opaque name="o">
+        <Dim name="/d1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>3d021e3e</Value>
+        </Attribute>
+    </Opaque>
+    <Opaque name="p">
+        <Dim name="/d1"/>
+        <Dim name="/d2"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>c9ba1dbe</Value>
+        </Attribute>
+    </Opaque>
+</Dataset>
+
+The data:
+{ {1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5}, {{1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5},{1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5},{1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5},{1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5},{1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5}} }
diff --git a/tests/dmr-testsuite/test_array_11.xml b/tests/dmr-testsuite/test_array_11.xml
new file mode 100644
index 0000000..dcd99fc
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_11.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+  xml:base="file:test_simple_11.xml"    
+  name="test_simple_11"
+  dapVersion="4.0"
+  dmrVersion="1.0">
+  <Dimension name="d1" size="5"/>
+  <Dimension name="d2" size="3"/>
+  
+  <Enumeration name="colors" basetype="Byte">
+    <EnumConst name="red" value="1"/>
+    <EnumConst name="green" value="2"/>
+    <EnumConst name="blue" value="3"/>
+  </Enumeration>
+  
+  <Enum name="e1" enum="colors">
+    <Dim name="d1"/>
+  </Enum>
+  
+  <Enum name="e2" enum="colors">
+    <Dim name="d1"/>
+    <Dim name="d2"/>
+  </Enum>
+  
+</Dataset>   
diff --git a/tests/dmr-testsuite/test_array_11.xml.baseline b/tests/dmr-testsuite/test_array_11.xml.baseline
new file mode 100644
index 0000000..bf68587
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_11.xml.baseline
@@ -0,0 +1,19 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:test_simple_11.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_11">
+    <Dimension name="d1" size="5"/>
+    <Dimension name="d2" size="3"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Enum name="e1" enum="/colors">
+        <Dim name="/d1"/>
+    </Enum>
+    <Enum name="e2" enum="/colors">
+        <Dim name="/d1"/>
+        <Dim name="/d2"/>
+    </Enum>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_11.xml.trans_base b/tests/dmr-testsuite/test_array_11.xml.trans_base
new file mode 100644
index 0000000..0e3f36e
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_11.xml.trans_base
@@ -0,0 +1,45 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:test_simple_11.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_11">
+    <Dimension name="d1" size="5"/>
+    <Dimension name="d2" size="3"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Enum name="e1" enum="/colors">
+        <Dim name="/d1"/>
+    </Enum>
+    <Enum name="e2" enum="/colors">
+        <Dim name="/d1"/>
+        <Dim name="/d2"/>
+    </Enum>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:test_simple_11.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_11">
+    <Dimension name="d1" size="5"/>
+    <Dimension name="d2" size="3"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Enum name="e1" enum="/colors">
+        <Dim name="/d1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>2c20d228</Value>
+        </Attribute>
+    </Enum>
+    <Enum name="e2" enum="/colors">
+        <Dim name="/d1"/>
+        <Dim name="/d2"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>c7a0f194</Value>
+        </Attribute>
+    </Enum>
+</Dataset>
+
+The data:
+{ {1, 1, 1, 1, 1}, {{1, 1, 1},{1, 1, 1},{1, 1, 1},{1, 1, 1},{1, 1, 1}} }
diff --git a/tests/dmr-testsuite/test_array_1_data.bin b/tests/dmr-testsuite/test_array_1_data.bin
new file mode 100644
index 0000000..8911582
Binary files /dev/null and b/tests/dmr-testsuite/test_array_1_data.bin differ
diff --git a/tests/dmr-testsuite/test_array_2.xml b/tests/dmr-testsuite/test_array_2.xml
new file mode 100644
index 0000000..f3060e6
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_2.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- First in a series of very simple tests. jhrg 7/10/12 -->
+
+<Dataset name="test_array_2" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_2.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <dap:Int32 name="x">
+    <Dim size="5"/>
+    <Dim size="4"/>
+  </dap:Int32>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_2.xml.baseline b/tests/dmr-testsuite/test_array_2.xml.baseline
new file mode 100644
index 0000000..d79fcee
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_2.xml.baseline
@@ -0,0 +1,9 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_2.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_2">
+    <Int32 name="x">
+        <Dim size="5"/>
+        <Dim size="4"/>
+    </Int32>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_2.xml.send_base b/tests/dmr-testsuite/test_array_2.xml.send_base
new file mode 100644
index 0000000..fef75f0
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_2.xml.send_base
@@ -0,0 +1,10 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_2.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_2">
+    <Int32 name="x">
+        <Dim size="5"/>
+        <Dim size="4"/>
+    </Int32>
+</Dataset>
+
+Response file: test_array_2_data.bin
diff --git a/tests/dmr-testsuite/test_array_2.xml.trans_base b/tests/dmr-testsuite/test_array_2.xml.trans_base
new file mode 100644
index 0000000..7e3c295
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_2.xml.trans_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_2.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_2">
+    <Int32 name="x">
+        <Dim size="5"/>
+        <Dim size="4"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_2.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_2">
+    <Int32 name="x">
+        <Dim size="5"/>
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>972f55fc</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ {{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789}} }
diff --git a/tests/dmr-testsuite/test_array_2_data.bin b/tests/dmr-testsuite/test_array_2_data.bin
new file mode 100644
index 0000000..73205f5
Binary files /dev/null and b/tests/dmr-testsuite/test_array_2_data.bin differ
diff --git a/tests/dmr-testsuite/test_array_3.xml b/tests/dmr-testsuite/test_array_3.xml
new file mode 100644
index 0000000..a11f352
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_3.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="test_array_3" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_3.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <Dimension name="row" size="5"/>   
+  
+  <dap:String name="x">
+    <Dim name="row"/>
+    <Dim size="3"/>
+  </dap:String>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_3.xml.baseline b/tests/dmr-testsuite/test_array_3.xml.baseline
new file mode 100644
index 0000000..8c990ad
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_3.xml.baseline
@@ -0,0 +1,10 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_3.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_3">
+    <Dimension name="row" size="5"/>
+    <String name="x">
+        <Dim name="/row"/>
+        <Dim size="3"/>
+    </String>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_3.xml.send_base b/tests/dmr-testsuite/test_array_3.xml.send_base
new file mode 100644
index 0000000..a1d71de
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_3.xml.send_base
@@ -0,0 +1,11 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_3.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_3">
+    <Dimension name="row" size="5"/>
+    <String name="x">
+        <Dim name="/row"/>
+        <Dim size="3"/>
+    </String>
+</Dataset>
+
+Response file: test_array_3_data.bin
diff --git a/tests/dmr-testsuite/test_array_3.xml.trans_base b/tests/dmr-testsuite/test_array_3.xml.trans_base
new file mode 100644
index 0000000..99e0353
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_3.xml.trans_base
@@ -0,0 +1,24 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_3.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_3">
+    <Dimension name="row" size="5"/>
+    <String name="x">
+        <Dim name="/row"/>
+        <Dim size="3"/>
+    </String>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_3.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_3">
+    <Dimension name="row" size="5"/>
+    <String name="x">
+        <Dim name="/row"/>
+        <Dim size="3"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>22983e08</Value>
+        </Attribute>
+    </String>
+</Dataset>
+
+The data:
+{ {{"Silly test string: 1", "Silly test string: 1", "Silly test string: 1"},{"Silly test string: 1", "Silly test string: 1", "Silly test string: 1"},{"Silly test string: 1", "Silly test string: 1", "Silly test string: 1"},{"Silly test string: 1", "Silly test string: 1", "Silly test string: 1"},{"Silly test string: 1", "Silly test string: 1", "Silly test string: 1"}} }
diff --git a/tests/dmr-testsuite/test_array_3_data.bin b/tests/dmr-testsuite/test_array_3_data.bin
new file mode 100644
index 0000000..dd75f54
Binary files /dev/null and b/tests/dmr-testsuite/test_array_3_data.bin differ
diff --git a/tests/dmr-testsuite/test_array_4.xml b/tests/dmr-testsuite/test_array_4.xml
new file mode 100644
index 0000000..400eeab
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_array_4" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_4.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <Dimension name="row" size="3"/>
+  <Dimension name="col" size="4"/>
+
+  <dap:Byte name="a">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:Byte>
+
+  <dap:Int16 name="b">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:Int16>
+
+  <dap:Int32 name="c">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:Int32>
+
+  <dap:UInt16 name="d">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:UInt16>
+
+  <dap:UInt32 name="e">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:UInt32>
+
+  <dap:Float32 name="f">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:Float32>
+
+  <dap:Float64 name="g">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:Float64>
+
+  <dap:String name="h">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:String>
+
+  <dap:URL name="i">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:URL>
+
+  <dap:Int32 name="x">
+    <Dim name="row"/>
+    <Dim size="5"/>
+  </dap:Int32>
+  
+  <dap:Int32 name="y">
+    <Dim size="5"/>
+    <Dim name="col"/>
+  </dap:Int32>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_4.xml.1.trans_base b/tests/dmr-testsuite/test_array_4.xml.1.trans_base
new file mode 100644
index 0000000..990f794
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.1.trans_base
@@ -0,0 +1,66 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>bb99ff8a</Value>
+        </Attribute>
+    </Byte>
+</Dataset>
+
+The data:
+{ {{255, 255, 255, 255},{255, 255, 255, 255},{255, 255, 255, 255}} }
diff --git a/tests/dmr-testsuite/test_array_4.xml.2.trans_base b/tests/dmr-testsuite/test_array_4.xml.2.trans_base
new file mode 100644
index 0000000..990f794
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.2.trans_base
@@ -0,0 +1,66 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>bb99ff8a</Value>
+        </Attribute>
+    </Byte>
+</Dataset>
+
+The data:
+{ {{255, 255, 255, 255},{255, 255, 255, 255},{255, 255, 255, 255}} }
diff --git a/tests/dmr-testsuite/test_array_4.xml.3.trans_base b/tests/dmr-testsuite/test_array_4.xml.3.trans_base
new file mode 100644
index 0000000..f0815f0
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.3.trans_base
@@ -0,0 +1,66 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="2"/>
+    <Dimension name="col" size="1"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>ffff0000</Value>
+        </Attribute>
+    </Byte>
+</Dataset>
+
+The data:
+{ {{255},{255}} }
diff --git a/tests/dmr-testsuite/test_array_4.xml.4.trans_base b/tests/dmr-testsuite/test_array_4.xml.4.trans_base
new file mode 100644
index 0000000..f0815f0
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.4.trans_base
@@ -0,0 +1,66 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="2"/>
+    <Dimension name="col" size="1"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>ffff0000</Value>
+        </Attribute>
+    </Byte>
+</Dataset>
+
+The data:
+{ {{255},{255}} }
diff --git a/tests/dmr-testsuite/test_array_4.xml.5.trans_base b/tests/dmr-testsuite/test_array_4.xml.5.trans_base
new file mode 100644
index 0000000..21e7193
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.5.trans_base
@@ -0,0 +1,80 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="2"/>
+    <Dimension name="col" size="1"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>ffff0000</Value>
+        </Attribute>
+    </Byte>
+    <Int16 name="b">
+        <Dim size="1"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6f6d1f7e</Value>
+        </Attribute>
+    </Int16>
+    <Int32 name="c">
+        <Dim size="3"/>
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>46997ac6</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ {{255},{255}}, {{32000}}, {{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789}} }
diff --git a/tests/dmr-testsuite/test_array_4.xml.6.trans_base b/tests/dmr-testsuite/test_array_4.xml.6.trans_base
new file mode 100644
index 0000000..8c45c5c
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.6.trans_base
@@ -0,0 +1,65 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>e787d509</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ {{123456789, 123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789}} }
diff --git a/tests/dmr-testsuite/test_array_4.xml.7.trans_base b/tests/dmr-testsuite/test_array_4.xml.7.trans_base
new file mode 100644
index 0000000..22a14a3
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.7.trans_base
@@ -0,0 +1,65 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="2"/>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>7c5e1ddb</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ {{123456789, 123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789}} }
diff --git a/tests/dmr-testsuite/test_array_4.xml.8.trans_base b/tests/dmr-testsuite/test_array_4.xml.8.trans_base
new file mode 100644
index 0000000..fe7b5fa
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.8.trans_base
@@ -0,0 +1,64 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Int32 name="c">
+        <Dim size="1"/>
+        <Dim size="2"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>114189cb</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ {{123456789, 123456789}} }
diff --git a/tests/dmr-testsuite/test_array_4.xml.baseline b/tests/dmr-testsuite/test_array_4.xml.baseline
new file mode 100644
index 0000000..0ab23fc
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.baseline
@@ -0,0 +1,51 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_4.xml.send_base b/tests/dmr-testsuite/test_array_4.xml.send_base
new file mode 100644
index 0000000..4907381
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.send_base
@@ -0,0 +1,52 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+Response file: test_array_4_data.bin
diff --git a/tests/dmr-testsuite/test_array_4.xml.trans_base b/tests/dmr-testsuite/test_array_4.xml.trans_base
new file mode 100644
index 0000000..6ac8b35
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_4.xml.trans_base
@@ -0,0 +1,136 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_4">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Byte name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>bb99ff8a</Value>
+        </Attribute>
+    </Byte>
+    <Int16 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>4a491560</Value>
+        </Attribute>
+    </Int16>
+    <Int32 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>46997ac6</Value>
+        </Attribute>
+    </Int32>
+    <UInt16 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>aba172e1</Value>
+        </Attribute>
+    </UInt16>
+    <UInt32 name="e">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6dee122e</Value>
+        </Attribute>
+    </UInt32>
+    <Float32 name="f">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>03d5492a</Value>
+        </Attribute>
+    </Float32>
+    <Float64 name="g">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>d6764865</Value>
+        </Attribute>
+    </Float64>
+    <String name="h">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>2004aea7</Value>
+        </Attribute>
+    </String>
+    <URL name="i">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>546a7c3d</Value>
+        </Attribute>
+    </URL>
+    <Int32 name="x">
+        <Dim name="/row"/>
+        <Dim size="5"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>e787d509</Value>
+        </Attribute>
+    </Int32>
+    <Int32 name="y">
+        <Dim size="5"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>972f55fc</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ {{255, 255, 255, 255},{255, 255, 255, 255},{255, 255, 255, 255}}, {{32000, 32000, 32000, 32000},{32000, 32000, 32000, 32000},{32000, 32000, 32000, 32000}}, {{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789}}, {{64000, 64000, 64000, 64000},{64000, 64000, 64000, 64000},{64000, 64000, 64000, 64000}}, {{4026531840, 4026531840, 4026531840, 4026531840},{4026531840, 4026531840, 4026531840, 4026531840},{402653 [...]
diff --git a/tests/dmr-testsuite/test_array_4_data.bin b/tests/dmr-testsuite/test_array_4_data.bin
new file mode 100644
index 0000000..4997818
Binary files /dev/null and b/tests/dmr-testsuite/test_array_4_data.bin differ
diff --git a/tests/dmr-testsuite/test_array_5.xml b/tests/dmr-testsuite/test_array_5.xml
new file mode 100644
index 0000000..000bd80
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_5.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_array_5" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_5.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Dimension name="row" size="3"/>
+  <Dimension name="col" size="4"/>
+  
+  <dap:Int8 name="a">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:Int8>
+  
+  <dap:UInt8 name="b">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:UInt8>
+  
+  <dap:Int64 name="c">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:Int64>
+  
+  <dap:UInt64 name="d">
+    <Dim name="row"/>
+    <Dim name="col"/>
+  </dap:UInt64>
+
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_5.xml.1.func_base b/tests/dmr-testsuite/test_array_5.xml.1.func_base
new file mode 100644
index 0000000..969a094
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_5.xml.1.func_base
@@ -0,0 +1,38 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_5">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Int8 name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int8>
+    <UInt8 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt8>
+    <Int64 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int64>
+    <UInt64 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt64>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Float64 name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>f02c5eb0</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {{0.127, 0.127, 0.127, 0.127},{0.127, 0.127, 0.127, 0.127},{0.127, 0.127, 0.127, 0.127}} }
diff --git a/tests/dmr-testsuite/test_array_5.xml.2.func_base b/tests/dmr-testsuite/test_array_5.xml.2.func_base
new file mode 100644
index 0000000..6e59a3b
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_5.xml.2.func_base
@@ -0,0 +1,38 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_5">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Int8 name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int8>
+    <UInt8 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt8>
+    <Int64 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int64>
+    <UInt64 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt64>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Float64 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>f3c062d7</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {{0.255, 0.255, 0.255, 0.255},{0.255, 0.255, 0.255, 0.255},{0.255, 0.255, 0.255, 0.255}} }
diff --git a/tests/dmr-testsuite/test_array_5.xml.3.func_base b/tests/dmr-testsuite/test_array_5.xml.3.func_base
new file mode 100644
index 0000000..e9bdae6
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_5.xml.3.func_base
@@ -0,0 +1,38 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_5">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Int8 name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int8>
+    <UInt8 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt8>
+    <Int64 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int64>
+    <UInt64 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt64>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Float64 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>38babd01</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {{72057594037927.9, 72057594037927.9, 72057594037927.9, 72057594037927.9},{72057594037927.9, 72057594037927.9, 72057594037927.9, 72057594037927.9},{72057594037927.9, 72057594037927.9, 72057594037927.9, 72057594037927.9}} }
diff --git a/tests/dmr-testsuite/test_array_5.xml.4.func_base b/tests/dmr-testsuite/test_array_5.xml.4.func_base
new file mode 100644
index 0000000..7c5d76a
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_5.xml.4.func_base
@@ -0,0 +1,38 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_5">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Int8 name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int8>
+    <UInt8 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt8>
+    <Int64 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int64>
+    <UInt64 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt64>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Float64 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>77e90ef8</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {{1.84467440737096e+16, 1.84467440737096e+16, 1.84467440737096e+16, 1.84467440737096e+16},{1.84467440737096e+16, 1.84467440737096e+16, 1.84467440737096e+16, 1.84467440737096e+16},{1.84467440737096e+16, 1.84467440737096e+16, 1.84467440737096e+16, 1.84467440737096e+16}} }
diff --git a/tests/dmr-testsuite/test_array_5.xml.baseline b/tests/dmr-testsuite/test_array_5.xml.baseline
new file mode 100644
index 0000000..c572b3d
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_5.xml.baseline
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_5">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Int8 name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int8>
+    <UInt8 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt8>
+    <Int64 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int64>
+    <UInt64 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt64>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_5.xml.send_base b/tests/dmr-testsuite/test_array_5.xml.send_base
new file mode 100644
index 0000000..5af317a
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_5.xml.send_base
@@ -0,0 +1,24 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_5">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Int8 name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int8>
+    <UInt8 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt8>
+    <Int64 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int64>
+    <UInt64 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt64>
+</Dataset>
+
+Response file: test_array_5_data.bin
diff --git a/tests/dmr-testsuite/test_array_5.xml.trans_base b/tests/dmr-testsuite/test_array_5.xml.trans_base
new file mode 100644
index 0000000..3615f69
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_5.xml.trans_base
@@ -0,0 +1,59 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_5">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Int8 name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int8>
+    <UInt8 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt8>
+    <Int64 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Int64>
+    <UInt64 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </UInt64>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_5">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Int8 name="a">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>82c3d109</Value>
+        </Attribute>
+    </Int8>
+    <UInt8 name="b">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>bb99ff8a</Value>
+        </Attribute>
+    </UInt8>
+    <Int64 name="c">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>38d2ecf4</Value>
+        </Attribute>
+    </Int64>
+    <UInt64 name="d">
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>46d91cd0</Value>
+        </Attribute>
+    </UInt64>
+</Dataset>
+
+The data:
+{ {{127, 127, 127, 127},{127, 127, 127, 127},{127, 127, 127, 127}}, {{255, 255, 255, 255},{255, 255, 255, 255},{255, 255, 255, 255}}, {{72057594037927935, 72057594037927935, 72057594037927935, 72057594037927935},{72057594037927935, 72057594037927935, 72057594037927935, 72057594037927935},{72057594037927935, 72057594037927935, 72057594037927935, 72057594037927935}}, {{18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615},{18446744073709551615, 18446744073 [...]
diff --git a/tests/dmr-testsuite/test_array_5_data.bin b/tests/dmr-testsuite/test_array_5_data.bin
new file mode 100644
index 0000000..4be202b
Binary files /dev/null and b/tests/dmr-testsuite/test_array_5_data.bin differ
diff --git a/tests/dmr-testsuite/test_array_6.1.xml b/tests/dmr-testsuite/test_array_6.1.xml
new file mode 100644
index 0000000..7febfd3
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.1.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_array_6" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_6.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Dimension name="row" size="3"/>
+  <Dimension name="col" size="4"/>
+  
+  <Structure name="a">
+    <Int32 name="i">
+        <Dim name="row"/>
+        <Dim size="6"/>
+    </Int32>
+    <Int32 name="j"/>
+    <Dim name="row"/>
+    <Dim name="col"/>   
+  </Structure>
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_6.1.xml.1.trans_base b/tests/dmr-testsuite/test_array_6.1.xml.1.trans_base
new file mode 100644
index 0000000..d724285
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.1.xml.1.trans_base
@@ -0,0 +1,36 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim size="6"/>
+        </Int32>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim size="6"/>
+        </Int32>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>108a44dc</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ {{{ {{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, 123456789, 123456789, 123456789, 123456789}}, 123456789 }, { {{123456789, 123456789, 123456789, 123456789, 12 [...]
diff --git a/tests/dmr-testsuite/test_array_6.1.xml.2.trans_base b/tests/dmr-testsuite/test_array_6.1.xml.2.trans_base
new file mode 100644
index 0000000..2867a7d
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.1.xml.2.trans_base
@@ -0,0 +1,35 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim size="6"/>
+        </Int32>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="2"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim size="6"/>
+        </Int32>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim size="1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>9dfcdf19</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ {{{ {{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/dmr-testsuite/test_array_6.1.xml.3.trans_base b/tests/dmr-testsuite/test_array_6.1.xml.3.trans_base
new file mode 100644
index 0000000..ae2d8da
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.1.xml.3.trans_base
@@ -0,0 +1,36 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim size="6"/>
+        </Int32>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim size="2"/>
+            <Dim size="3"/>
+        </Int32>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>dcf2f8b1</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ {{{ {{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, 123456789}}, 123456789 }, { {{123456789, 123456789, 123456789},{123456789, 12345678 [...]
diff --git a/tests/dmr-testsuite/test_array_6.1.xml.4.trans_base b/tests/dmr-testsuite/test_array_6.1.xml.4.trans_base
new file mode 100644
index 0000000..380c47f
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.1.xml.4.trans_base
@@ -0,0 +1,34 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim size="6"/>
+        </Int32>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="1"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim size="2"/>
+        </Int32>
+        <Dim name="/row"/>
+        <Dim size="1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>114189cb</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ {{{ {{123456789, 123456789}} }}} }
diff --git a/tests/dmr-testsuite/test_array_6.2.xml b/tests/dmr-testsuite/test_array_6.2.xml
new file mode 100644
index 0000000..ffe6be6
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.2.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_array_6" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_6.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Dimension name="row" size="3"/>
+  <Dimension name="col" size="4"/>
+  
+  <Structure name="a">
+    <Int32 name="i">
+        <Dim name="row"/>
+        <Dim name="col"/>   
+    </Int32>
+    <Int32 name="j"/>
+  </Structure>
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_6.2.xml.1.trans_base b/tests/dmr-testsuite/test_array_6.2.xml.1.trans_base
new file mode 100644
index 0000000..3eb7cfc
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.2.xml.1.trans_base
@@ -0,0 +1,32 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Int32 name="j"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Int32 name="j"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>2da3e534</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { {{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789}}, 123456789 } }
diff --git a/tests/dmr-testsuite/test_array_6.2.xml.2.trans_base b/tests/dmr-testsuite/test_array_6.2.xml.2.trans_base
new file mode 100644
index 0000000..eda3ac9
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.2.xml.2.trans_base
@@ -0,0 +1,31 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Int32 name="j"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>46997ac6</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { {{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789}} } }
diff --git a/tests/dmr-testsuite/test_array_6.2.xml.3.trans_base b/tests/dmr-testsuite/test_array_6.2.xml.3.trans_base
new file mode 100644
index 0000000..e29c220
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.2.xml.3.trans_base
@@ -0,0 +1,29 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Int32 name="j"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim size="1"/>
+            <Dim size="2"/>
+        </Int32>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>114189cb</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { {{123456789, 123456789}} } }
diff --git a/tests/dmr-testsuite/test_array_6.2.xml.4.trans_base b/tests/dmr-testsuite/test_array_6.2.xml.4.trans_base
new file mode 100644
index 0000000..5fede31
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.2.xml.4.trans_base
@@ -0,0 +1,30 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Int32 name="j"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="2"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim size="2"/>
+        </Int32>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b2871a70</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { {{123456789, 123456789},{123456789, 123456789}} } }
diff --git a/tests/dmr-testsuite/test_array_6.2.xml.5.trans_base b/tests/dmr-testsuite/test_array_6.2.xml.5.trans_base
new file mode 100644
index 0000000..4458da6
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.2.xml.5.trans_base
@@ -0,0 +1,26 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Int32 name="j"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Structure name="a">
+        <Int32 name="j"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>18df6c9e</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { 123456789 } }
diff --git a/tests/dmr-testsuite/test_array_6.xml b/tests/dmr-testsuite/test_array_6.xml
new file mode 100644
index 0000000..e1feb9c
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_array_6" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_6.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Dimension name="row" size="3"/>
+  <Dimension name="col" size="4"/>
+  
+  <Structure name="a">
+    <Int32 name="i"/>
+    <Int32 name="j"/>
+    <Dim name="row"/>
+    <Dim name="col"/>   
+  </Structure>
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_6.xml.1.trans_base b/tests/dmr-testsuite/test_array_6.xml.1.trans_base
new file mode 100644
index 0000000..91107f7
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.xml.1.trans_base
@@ -0,0 +1,30 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>d9ce8457</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ {{{ 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/dmr-testsuite/test_array_6.xml.2.trans_base b/tests/dmr-testsuite/test_array_6.xml.2.trans_base
new file mode 100644
index 0000000..aedafc8
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.xml.2.trans_base
@@ -0,0 +1,30 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="2"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>a439ad98</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ {{{ 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }},{{ 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }}} }
diff --git a/tests/dmr-testsuite/test_array_6.xml.3.trans_base b/tests/dmr-testsuite/test_array_6.xml.3.trans_base
new file mode 100644
index 0000000..4fdcbf4
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.xml.3.trans_base
@@ -0,0 +1,29 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="2"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim size="2"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6f7d7361</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ {{{ 123456789, 123456789 }, { 123456789, 123456789 }},{{ 123456789, 123456789 }, { 123456789, 123456789 }}} }
diff --git a/tests/dmr-testsuite/test_array_6.xml.baseline b/tests/dmr-testsuite/test_array_6.xml.baseline
new file mode 100644
index 0000000..997d51c
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.xml.baseline
@@ -0,0 +1,13 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_6.xml.send_base b/tests/dmr-testsuite/test_array_6.xml.send_base
new file mode 100644
index 0000000..8b84af1
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.xml.send_base
@@ -0,0 +1,14 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
+Response file: test_array_6_data.bin
diff --git a/tests/dmr-testsuite/test_array_6.xml.trans_base b/tests/dmr-testsuite/test_array_6.xml.trans_base
new file mode 100644
index 0000000..91107f7
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_6.xml.trans_base
@@ -0,0 +1,30 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_6">
+    <Dimension name="row" size="3"/>
+    <Dimension name="col" size="4"/>
+    <Structure name="a">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/row"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>d9ce8457</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ {{{ 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/dmr-testsuite/test_array_6_data.bin b/tests/dmr-testsuite/test_array_6_data.bin
new file mode 100644
index 0000000..a34dfd7
Binary files /dev/null and b/tests/dmr-testsuite/test_array_6_data.bin differ
diff --git a/tests/dmr-testsuite/test_array_7.1.xml b/tests/dmr-testsuite/test_array_7.1.xml
new file mode 100644
index 0000000..ecd863a
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.1.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_array_7" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_7.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <Dimension name="row" size="4"/>
+  <Dimension name="col" size="5"/>
+
+  <Sequence name="s">
+    <Int32 name="i1">
+      <Dim name="row"/>
+      <Dim name="col"/>
+    </Int32>
+    <String name="s"/>
+  </Sequence>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_7.1.xml.1.trans_base b/tests/dmr-testsuite/test_array_7.1.xml.1.trans_base
new file mode 100644
index 0000000..e31c178
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.1.xml.1.trans_base
@@ -0,0 +1,32 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>0193e1cb</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ { { {{123456789, 123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789}}, "Silly test string: 1" }, { {{123456789, 123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789}}, "Sil [...]
diff --git a/tests/dmr-testsuite/test_array_7.1.xml.2.trans_base b/tests/dmr-testsuite/test_array_7.1.xml.2.trans_base
new file mode 100644
index 0000000..ed6de1b
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.1.xml.2.trans_base
@@ -0,0 +1,31 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b43945c2</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ { { {{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, 123456789, 123456789},{123456789, 123456789, 123456789, 123456789, 123456789}} }, { {{123456789, 123456789,  [...]
diff --git a/tests/dmr-testsuite/test_array_7.1.xml.3.trans_base b/tests/dmr-testsuite/test_array_7.1.xml.3.trans_base
new file mode 100644
index 0000000..b3a34ee
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.1.xml.3.trans_base
@@ -0,0 +1,29 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim size="1"/>
+            <Dim size="1"/>
+        </Int32>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b2871a70</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ { { {{123456789}} }, { {{123456789}} }, { {{123456789}} }, { {{123456789}} } } }
diff --git a/tests/dmr-testsuite/test_array_7.1.xml.4.trans_base b/tests/dmr-testsuite/test_array_7.1.xml.4.trans_base
new file mode 100644
index 0000000..9456876
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.1.xml.4.trans_base
@@ -0,0 +1,29 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim size="3"/>
+            <Dim size="2"/>
+        </Int32>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>d9ce8457</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ { { {{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/dmr-testsuite/test_array_7.1.xml.5.trans_base b/tests/dmr-testsuite/test_array_7.1.xml.5.trans_base
new file mode 100644
index 0000000..203b524
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.1.xml.5.trans_base
@@ -0,0 +1,32 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="2"/>
+    <Dimension name="col" size="2"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>0ee272dc</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ { { {{123456789, 123456789},{123456789, 123456789}}, "Silly test string: 1" }, { {{123456789, 123456789},{123456789, 123456789}}, "Silly test string: 1" }, { {{123456789, 123456789},{123456789, 123456789}}, "Silly test string: 1" }, { {{123456789, 123456789},{123456789, 123456789}}, "Silly test string: 1" } } }
diff --git a/tests/dmr-testsuite/test_array_7.1.xml.6.trans_base b/tests/dmr-testsuite/test_array_7.1.xml.6.trans_base
new file mode 100644
index 0000000..8b3fe56
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.1.xml.6.trans_base
@@ -0,0 +1,31 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="2"/>
+    <Dimension name="col" size="2"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>a439ad98</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ { { {{123456789, 123456789},{123456789, 123456789}} }, { {{123456789, 123456789},{123456789, 123456789}} }, { {{123456789, 123456789},{123456789, 123456789}} }, { {{123456789, 123456789},{123456789, 123456789}} } } }
diff --git a/tests/dmr-testsuite/test_array_7.2.xml b/tests/dmr-testsuite/test_array_7.2.xml
new file mode 100644
index 0000000..1991de8
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.2.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_array_7" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_7.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <Dimension name="row" size="4"/>
+  <Dimension name="col" size="5"/>
+
+  <Sequence name="s">
+    <Dim size="4"/>
+    <Int32 name="i1">
+      <Dim name="row"/>
+      <Dim name="col"/>
+    </Int32>
+    <String name="s"/>
+  </Sequence>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_7.2.xml.1.trans_base b/tests/dmr-testsuite/test_array_7.2.xml.1.trans_base
new file mode 100644
index 0000000..2370abe
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.2.xml.1.trans_base
@@ -0,0 +1,33 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+        <Dim size="4"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="2"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>82a5d12e</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{ { {{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, 123456789},{123456789, 123456789},{123456789, 123456789},{123456789, 123 [...]
diff --git a/tests/dmr-testsuite/test_array_7.2.xml.2.trans_base b/tests/dmr-testsuite/test_array_7.2.xml.2.trans_base
new file mode 100644
index 0000000..ccb2b4c
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.2.xml.2.trans_base
@@ -0,0 +1,32 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+        <Dim size="4"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="col" size="2"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim size="1"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>d2cdfa69</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{ { {{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/dmr-testsuite/test_array_7.2.xml.3.trans_base b/tests/dmr-testsuite/test_array_7.2.xml.3.trans_base
new file mode 100644
index 0000000..5a0664c
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.2.xml.3.trans_base
@@ -0,0 +1,33 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+        <Dim size="4"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="2"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Dim size="1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>d2cdfa69</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{ { {{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/dmr-testsuite/test_array_7.2.xml.4.trans_base b/tests/dmr-testsuite/test_array_7.2.xml.4.trans_base
new file mode 100644
index 0000000..176958c
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.2.xml.4.trans_base
@@ -0,0 +1,32 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="row" size="4"/>
+    <Dimension name="col" size="5"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim name="/row"/>
+            <Dim name="/col"/>
+        </Int32>
+        <String name="s"/>
+        <Dim size="4"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Dimension name="col" size="2"/>
+    <Sequence name="s">
+        <Int32 name="i1">
+            <Dim size="1"/>
+            <Dim name="/col"/>
+        </Int32>
+        <Dim size="1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6f7d7361</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{ { {{123456789, 123456789}} }, { {{123456789, 123456789}} }, { {{123456789, 123456789}} }, { {{123456789, 123456789}} } }} }
diff --git a/tests/dmr-testsuite/test_array_7.xml b/tests/dmr-testsuite/test_array_7.xml
new file mode 100644
index 0000000..ccddbb6
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_array_7" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_7.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+    <Sequence name="s">
+        <Dim size="2"/>
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Sequence>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_7.xml.1.trans_base b/tests/dmr-testsuite/test_array_7.xml.1.trans_base
new file mode 100644
index 0000000..ab441a9
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.xml.1.trans_base
@@ -0,0 +1,24 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>766f5e81</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{ { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } }, { { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } }} }
diff --git a/tests/dmr-testsuite/test_array_7.xml.2.trans_base b/tests/dmr-testsuite/test_array_7.xml.2.trans_base
new file mode 100644
index 0000000..9c915b2
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.xml.2.trans_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <Dim size="2"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6f7d7361</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{ { 123456789 }, { 123456789 }, { 123456789 }, { 123456789 } }, { { 123456789 }, { 123456789 }, { 123456789 }, { 123456789 } }} }
diff --git a/tests/dmr-testsuite/test_array_7.xml.3.trans_base b/tests/dmr-testsuite/test_array_7.xml.3.trans_base
new file mode 100644
index 0000000..276ba96
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.xml.3.trans_base
@@ -0,0 +1,24 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b617a898</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{ { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } }} }
diff --git a/tests/dmr-testsuite/test_array_7.xml.4.trans_base b/tests/dmr-testsuite/test_array_7.xml.4.trans_base
new file mode 100644
index 0000000..911fb46
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.xml.4.trans_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <Dim size="1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b2871a70</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{ { 123456789 }, { 123456789 }, { 123456789 }, { 123456789 } }} }
diff --git a/tests/dmr-testsuite/test_array_7.xml.baseline b/tests/dmr-testsuite/test_array_7.xml.baseline
new file mode 100644
index 0000000..c934bf0
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.xml.baseline
@@ -0,0 +1,10 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+    </Sequence>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_7.xml.trans_base b/tests/dmr-testsuite/test_array_7.xml.trans_base
new file mode 100644
index 0000000..ab441a9
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_7.xml.trans_base
@@ -0,0 +1,24 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>766f5e81</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{ { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } }, { { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } }} }
diff --git a/tests/dmr-testsuite/test_array_8.xml b/tests/dmr-testsuite/test_array_8.xml
new file mode 100644
index 0000000..91de607
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_8.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_array_8" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_array_8.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  <Dimension name="col" size="3"/>
+  <Sequence name="s">
+    <Dim size="2"/>
+    <Dim name="col"/>
+    <Int32 name="i1"/>
+    <String name="s"/>
+  </Sequence>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_array_8.xml.1.trans_base b/tests/dmr-testsuite/test_array_8.xml.1.trans_base
new file mode 100644
index 0000000..823d66d
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_8.xml.1.trans_base
@@ -0,0 +1,27 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_8">
+    <Dimension name="col" size="3"/>
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+        <Dim name="/col"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_8">
+    <Dimension name="col" size="2"/>
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <Dim size="1"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6f7d7361</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{{ { 123456789 }, { 123456789 }, { 123456789 }, { 123456789 } }, { { 123456789 }, { 123456789 }, { 123456789 }, { 123456789 } }}} }
diff --git a/tests/dmr-testsuite/test_array_8.xml.baseline b/tests/dmr-testsuite/test_array_8.xml.baseline
new file mode 100644
index 0000000..98e2de9
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_8.xml.baseline
@@ -0,0 +1,12 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_8">
+    <Dimension name="col" size="3"/>
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+        <Dim name="/col"/>
+    </Sequence>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_array_8.xml.trans_base b/tests/dmr-testsuite/test_array_8.xml.trans_base
new file mode 100644
index 0000000..03083b6
--- /dev/null
+++ b/tests/dmr-testsuite/test_array_8.xml.trans_base
@@ -0,0 +1,28 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_8">
+    <Dimension name="col" size="3"/>
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+        <Dim name="/col"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_array_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_array_8">
+    <Dimension name="col" size="3"/>
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Dim size="2"/>
+        <Dim name="/col"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>f95dfb1c</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ {{{ { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } }, { { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } }, { { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } }},{{ { 123 [...]
diff --git a/tests/dmr-testsuite/test_escaped_paths.xml b/tests/dmr-testsuite/test_escaped_paths.xml
new file mode 100644
index 0000000..afd82e7
--- /dev/null
+++ b/tests/dmr-testsuite/test_escaped_paths.xml
@@ -0,0 +1,69 @@
+<Dataset name="example"
+       dapVersion="4.0"
+       dmrVersion="1.0"
+       xmlns="http://xml.opendap.org/ns/DAP/4.0#">
+
+<Enumeration name="e1" basetype="UInt8">
+  <EnumConst name="econst1" value="1"/>
+  <EnumConst name="econst2" value="2"/>
+</Enumeration>
+
+<Dimension name="d1" size="10"/>
+<Dimension name="lat" size="20"/>
+<Dimension name="lon" size="20"/>
+
+<Int32 name="x"/>
+<Float32 name="lat">
+  <Dim name="/lat"/>
+</Float32>
+<Float32 name="lon">
+  <Dim name="/lon"/>
+</Float32>
+<Structure name="y">
+  <Opaque name="f1"/>
+  <Attribute name="a1" type="Int32"/>
+  <Attribute name="a2" type="Float64">
+    <Value value="7.5"/>    
+    <Value>10</Value>
+  </Attribute>  
+  <!-- Structure dimensions -->
+  <Dim size="*"/>
+  <Dim name="/d1"/>
+  <Dim size="10"/>
+</Structure>
+
+<Group name="g1">
+  <Dimension name="d1" size="10"/>
+  <Dimension name="d2" size="20"/>
+
+  <Float32 name="tempb">
+    <Dim name="/lat"/>
+    <Dim name="/lon"/>
+    <Map name="/lat"/>
+    <Map name="/lon"/>
+  </Float32>
+  <Enum enum="/e1" name="evar"/>
+
+</Group>
+
+<!-- Test FQN name processing -->
+<Group name="g.@/\$">
+<!-- Provide a dimension with a name that needs escaping "lon/2.\" -->
+<Dimension name="lon/2.\" size="20"/>
+</Group>
+
+<!-- reference the dimension and group with funny names -->
+<Int32 name="funny">
+  <Dim name="/g\.@\/\\$/lon\/2\.\\"/>
+</Int32>
+
+<!-- embedded xml example; dap4.rng needs work
+<OtherXML>
+<anyelement1 name="5">
+<anyelement2>any text</anyelement2>
+</anyelement1>
+</OtherXML>
+-->
+
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_1.xml b/tests/dmr-testsuite/test_simple_1.xml
new file mode 100644
index 0000000..0ca869a
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_1.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- First in a series of very simple tests. jhrg 7/10/12 -->
+
+<Dataset name="test_simple_1" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_1.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <dap:Int32 name="x"/>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_1.xml.baseline b/tests/dmr-testsuite/test_simple_1.xml.baseline
new file mode 100644
index 0000000..b26c94b
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_1.xml.baseline
@@ -0,0 +1,6 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_1">
+    <Int32 name="x"/>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_1.xml.send_base b/tests/dmr-testsuite/test_simple_1.xml.send_base
new file mode 100644
index 0000000..0cdceaa
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_1.xml.send_base
@@ -0,0 +1,7 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_1">
+    <Int32 name="x"/>
+</Dataset>
+
+Response file: test_simple_1_data.bin
diff --git a/tests/dmr-testsuite/test_simple_1.xml.trans_base b/tests/dmr-testsuite/test_simple_1.xml.trans_base
new file mode 100644
index 0000000..ae52ffd
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_1.xml.trans_base
@@ -0,0 +1,17 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_1">
+    <Int32 name="x"/>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_1.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_1">
+    <Int32 name="x">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>18df6c9e</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ 123456789 }
diff --git a/tests/dmr-testsuite/test_simple_10.xml b/tests/dmr-testsuite/test_simple_10.xml
new file mode 100644
index 0000000..f31f1f9
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_10.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_10" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_10.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+    
+  <Opaque name="o"/>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_10.xml.baseline b/tests/dmr-testsuite/test_simple_10.xml.baseline
new file mode 100644
index 0000000..1e55ff5
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_10.xml.baseline
@@ -0,0 +1,6 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_10.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_10">
+    <Opaque name="o"/>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_10.xml.trans_base b/tests/dmr-testsuite/test_simple_10.xml.trans_base
new file mode 100644
index 0000000..b9b6c49
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_10.xml.trans_base
@@ -0,0 +1,17 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_10.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_10">
+    <Opaque name="o"/>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_10.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_10">
+    <Opaque name="o">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>470b99f4</Value>
+        </Attribute>
+    </Opaque>
+</Dataset>
+
+The data:
+{ 1,2,3,4,5 }
diff --git a/tests/dmr-testsuite/test_simple_1_data.bin b/tests/dmr-testsuite/test_simple_1_data.bin
new file mode 100644
index 0000000..939997f
Binary files /dev/null and b/tests/dmr-testsuite/test_simple_1_data.bin differ
diff --git a/tests/dmr-testsuite/test_simple_2.xml b/tests/dmr-testsuite/test_simple_2.xml
new file mode 100644
index 0000000..6156ba6
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_2.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- First in a series of very simple tests. jhrg 7/10/12 -->
+
+<Dataset name="test_simple_2" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_2.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <Byte name="b"/>
+  
+  <Int8 name="i8"/>
+  <UInt8 name="ui8"/>
+  
+  <Int16 name="i16"/>
+  <UInt16 name="ui16"/>
+  
+  <Int32 name="i32"/>
+  <UInt32 name="ui32"/>
+  
+  <Int64 name="i64"/>
+  <UInt64 name="ui64"/>
+  
+  <Float32 name="f32"/>
+  <Float64 name="f64"/>
+
+  <String name="s"/>
+  <URL name="u"/>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_2.xml.baseline b/tests/dmr-testsuite/test_simple_2.xml.baseline
new file mode 100644
index 0000000..1650f79
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_2.xml.baseline
@@ -0,0 +1,18 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_2.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_2">
+    <Byte name="b"/>
+    <Int8 name="i8"/>
+    <UInt8 name="ui8"/>
+    <Int16 name="i16"/>
+    <UInt16 name="ui16"/>
+    <Int32 name="i32"/>
+    <UInt32 name="ui32"/>
+    <Int64 name="i64"/>
+    <UInt64 name="ui64"/>
+    <Float32 name="f32"/>
+    <Float64 name="f64"/>
+    <String name="s"/>
+    <URL name="u"/>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_2.xml.send_base b/tests/dmr-testsuite/test_simple_2.xml.send_base
new file mode 100644
index 0000000..8f151c9
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_2.xml.send_base
@@ -0,0 +1,19 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_2.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_2">
+    <Byte name="b"/>
+    <Int8 name="i8"/>
+    <UInt8 name="ui8"/>
+    <Int16 name="i16"/>
+    <UInt16 name="ui16"/>
+    <Int32 name="i32"/>
+    <UInt32 name="ui32"/>
+    <Int64 name="i64"/>
+    <UInt64 name="ui64"/>
+    <Float32 name="f32"/>
+    <Float64 name="f64"/>
+    <String name="s"/>
+    <URL name="u"/>
+</Dataset>
+
+Response file: test_simple_2_data.bin
diff --git a/tests/dmr-testsuite/test_simple_2.xml.trans_base b/tests/dmr-testsuite/test_simple_2.xml.trans_base
new file mode 100644
index 0000000..ccd53c4
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_2.xml.trans_base
@@ -0,0 +1,89 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_2.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_2">
+    <Byte name="b"/>
+    <Int8 name="i8"/>
+    <UInt8 name="ui8"/>
+    <Int16 name="i16"/>
+    <UInt16 name="ui16"/>
+    <Int32 name="i32"/>
+    <UInt32 name="ui32"/>
+    <Int64 name="i64"/>
+    <UInt64 name="ui64"/>
+    <Float32 name="f32"/>
+    <Float64 name="f64"/>
+    <String name="s"/>
+    <URL name="u"/>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_2.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_2">
+    <Byte name="b">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>ff000000</Value>
+        </Attribute>
+    </Byte>
+    <Int8 name="i8">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>12b88320</Value>
+        </Attribute>
+    </Int8>
+    <UInt8 name="ui8">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>ff000000</Value>
+        </Attribute>
+    </UInt8>
+    <Int16 name="i16">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6f6d1f7e</Value>
+        </Attribute>
+    </Int16>
+    <UInt16 name="ui16">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>1cb109fd</Value>
+        </Attribute>
+    </UInt16>
+    <Int32 name="i32">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>18df6c9e</Value>
+        </Attribute>
+    </Int32>
+    <UInt32 name="ui32">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>9cf92d00</Value>
+        </Attribute>
+    </UInt32>
+    <Int64 name="i64">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>0c463091</Value>
+        </Attribute>
+    </Int64>
+    <UInt64 name="ui64">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>2144df1c</Value>
+        </Attribute>
+    </UInt64>
+    <Float32 name="f32">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>1ae0f285</Value>
+        </Attribute>
+    </Float32>
+    <Float64 name="f64">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>946c3797</Value>
+        </Attribute>
+    </Float64>
+    <String name="s">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>3d9a4edd</Value>
+        </Attribute>
+    </String>
+    <URL name="u">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>08f792c4</Value>
+        </Attribute>
+    </URL>
+</Dataset>
+
+The data:
+{ 255, 127, 255, 32000, 64000, 123456789, 4026531840, 72057594037927935, 18446744073709551615, 99.999, 99.999, "Silly test string: 1", "http://dcz.gso.uri.edu/avhrr-archive/archive.html" }
diff --git a/tests/dmr-testsuite/test_simple_2_data.bin b/tests/dmr-testsuite/test_simple_2_data.bin
new file mode 100644
index 0000000..26be2eb
Binary files /dev/null and b/tests/dmr-testsuite/test_simple_2_data.bin differ
diff --git a/tests/dmr-testsuite/test_simple_3.xml b/tests/dmr-testsuite/test_simple_3.xml
new file mode 100644
index 0000000..5068261
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_3" dapVersion="4.0" dmrVersion="1.0" xmlns="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <!-- Test enumeration definitions -->
+  <Enumeration name="e1" basetype="UInt8">
+    <EnumConst name="econst1" value="1"/>
+    <EnumConst name="econst2" value="2"/>
+  </Enumeration>
+
+  <Int32 name="x"/>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_3.xml.baseline b/tests/dmr-testsuite/test_simple_3.xml.baseline
new file mode 100644
index 0000000..088be2f
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3.xml.baseline
@@ -0,0 +1,10 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="test_simple_3">
+    <Enumeration name="e1" basetype="UInt8">
+        <EnumConst name="econst1" value="1"/>
+        <EnumConst name="econst2" value="2"/>
+    </Enumeration>
+    <Int32 name="x"/>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_3.xml.send_base b/tests/dmr-testsuite/test_simple_3.xml.send_base
new file mode 100644
index 0000000..52278e3
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3.xml.send_base
@@ -0,0 +1,11 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="test_simple_3">
+    <Enumeration name="e1" basetype="UInt8">
+        <EnumConst name="econst1" value="1"/>
+        <EnumConst name="econst2" value="2"/>
+    </Enumeration>
+    <Int32 name="x"/>
+</Dataset>
+
+Response file: test_simple_3_data.bin
diff --git a/tests/dmr-testsuite/test_simple_3.xml.trans_base b/tests/dmr-testsuite/test_simple_3.xml.trans_base
new file mode 100644
index 0000000..95c0db6
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3.xml.trans_base
@@ -0,0 +1,25 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="test_simple_3">
+    <Enumeration name="e1" basetype="UInt8">
+        <EnumConst name="econst1" value="1"/>
+        <EnumConst name="econst2" value="2"/>
+    </Enumeration>
+    <Int32 name="x"/>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="test_simple_3">
+    <Enumeration name="e1" basetype="UInt8">
+        <EnumConst name="econst1" value="1"/>
+        <EnumConst name="econst2" value="2"/>
+    </Enumeration>
+    <Int32 name="x">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>18df6c9e</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ 123456789 }
diff --git a/tests/dmr-testsuite/test_simple_3_data.bin b/tests/dmr-testsuite/test_simple_3_data.bin
new file mode 100644
index 0000000..44108bc
Binary files /dev/null and b/tests/dmr-testsuite/test_simple_3_data.bin differ
diff --git a/tests/dmr-testsuite/test_simple_3_error_1.xml b/tests/dmr-testsuite/test_simple_3_error_1.xml
new file mode 100644
index 0000000..5686798
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3_error_1.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="example" dapVersion="4.0" dmrVersion="1.0" xmlns="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <!-- Bad EnumConst; it must be an integer value -->
+  <Enumeration name="e1" basetype="UInt8">
+    <EnumConst name="econst1" value="1"/>
+    <EnumConst name="econst2" value="not_an_integer"/>
+  </Enumeration>
+
+  <Int32 name="x"/>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_3_error_1.xml.baseline b/tests/dmr-testsuite/test_simple_3_error_1.xml.baseline
new file mode 100644
index 0000000..2d9f6e0
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3_error_1.xml.baseline
@@ -0,0 +1,2 @@
+Error: At line 1: Expected an integer value for an Enumeration constant, got 'not_an_integer' instead.
+At line 1: The document contained unbalanced tags.
diff --git a/tests/dmr-testsuite/test_simple_3_error_2.xml b/tests/dmr-testsuite/test_simple_3_error_2.xml
new file mode 100644
index 0000000..6f28cd4
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3_error_2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="example" dapVersion="4.0" dmrVersion="1.0" xmlns="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <!-- Bad basetype for an Enumeration -->
+  <Enumeration name="e1" basetype="Float64">
+    <EnumConst name="econst1" value="1"/>
+    <EnumConst name="econst2" value="2"/>
+  </Enumeration>
+
+  <Int32 name="x"/>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_3_error_2.xml.baseline b/tests/dmr-testsuite/test_simple_3_error_2.xml.baseline
new file mode 100644
index 0000000..b6585a6
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3_error_2.xml.baseline
@@ -0,0 +1,3 @@
+Error: At line 1: The Enumeration 'e1' must have an integer type, instead the type 'Float64' was used.
+At line 1: Expected an Attribute, Enumeration, Dimension, Group or variable element; found 'Enumeration' instead.
+At line 1: The document contained unbalanced tags.
diff --git a/tests/dmr-testsuite/test_simple_3_error_3.xml b/tests/dmr-testsuite/test_simple_3_error_3.xml
new file mode 100644
index 0000000..c8d6f24
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3_error_3.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="example" dapVersion="4.0" dmrVersion="1.0" xmlns="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <!-- Bad EnumConst; the value is too big -->
+  <Enumeration name="e1" basetype="UInt8">
+    <EnumConst name="econst1" value="1"/>
+    <EnumConst name="econst2" value="257"/>
+  </Enumeration>
+
+  <Int32 name="x"/>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_3_error_3.xml.baseline b/tests/dmr-testsuite/test_simple_3_error_3.xml.baseline
new file mode 100644
index 0000000..8d85347
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_3_error_3.xml.baseline
@@ -0,0 +1,2 @@
+Error: At line 1: In an Enumeration constant, the value '257' cannot fit in a variable of type 'UInt8'.
+At line 1: The document contained unbalanced tags.
diff --git a/tests/dmr-testsuite/test_simple_4.xml b/tests/dmr-testsuite/test_simple_4.xml
new file mode 100644
index 0000000..431954a
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_4.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Attributes -->
+
+<Dataset name="test_simple_4" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_4.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <dap:Int32 name="x">
+    <Attribute name="long_name" type="String">
+      <Value>x_axis_value</Value>
+    </Attribute>
+  </dap:Int32>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_4.xml.baseline b/tests/dmr-testsuite/test_simple_4.xml.baseline
new file mode 100644
index 0000000..f14b44e
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_4.xml.baseline
@@ -0,0 +1,10 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_4">
+    <Int32 name="x">
+        <Attribute name="long_name" type="String">
+            <Value>x_axis_value</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_4.xml.send_base b/tests/dmr-testsuite/test_simple_4.xml.send_base
new file mode 100644
index 0000000..938b2c5
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_4.xml.send_base
@@ -0,0 +1,11 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_4">
+    <Int32 name="x">
+        <Attribute name="long_name" type="String">
+            <Value>x_axis_value</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+Response file: test_simple_4_data.bin
diff --git a/tests/dmr-testsuite/test_simple_4.xml.trans_base b/tests/dmr-testsuite/test_simple_4.xml.trans_base
new file mode 100644
index 0000000..df5b730
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_4.xml.trans_base
@@ -0,0 +1,24 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_4">
+    <Int32 name="x">
+        <Attribute name="long_name" type="String">
+            <Value>x_axis_value</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_4.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_4">
+    <Int32 name="x">
+        <Attribute name="long_name" type="String">
+            <Value>x_axis_value</Value>
+        </Attribute>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>18df6c9e</Value>
+        </Attribute>
+    </Int32>
+</Dataset>
+
+The data:
+{ 123456789 }
diff --git a/tests/dmr-testsuite/test_simple_4_data.bin b/tests/dmr-testsuite/test_simple_4_data.bin
new file mode 100644
index 0000000..b24f173
Binary files /dev/null and b/tests/dmr-testsuite/test_simple_4_data.bin differ
diff --git a/tests/dmr-testsuite/test_simple_5.xml b/tests/dmr-testsuite/test_simple_5.xml
new file mode 100644
index 0000000..e136d31
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_5.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Attributes -->
+
+<Dataset name="test_simple_5" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_5.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <dap:Int8 name="i"/>
+  <dap:Int16 name="j"/>
+  <dap:Int32 name="k"/>
+  <dap:Int64 name="z"/>
+ 
+  <dap:Byte name="ui"/>
+  <dap:UInt8 name="uii"/>
+  <dap:UInt16 name="uj"/>
+  <dap:UInt32 name="uk"/>
+  <dap:UInt64 name="uz"/>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_5.xml.baseline b/tests/dmr-testsuite/test_simple_5.xml.baseline
new file mode 100644
index 0000000..0405998
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_5.xml.baseline
@@ -0,0 +1,14 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_5">
+    <Int8 name="i"/>
+    <Int16 name="j"/>
+    <Int32 name="k"/>
+    <Int64 name="z"/>
+    <Byte name="ui"/>
+    <UInt8 name="uii"/>
+    <UInt16 name="uj"/>
+    <UInt32 name="uk"/>
+    <UInt64 name="uz"/>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_5.xml.send_base b/tests/dmr-testsuite/test_simple_5.xml.send_base
new file mode 100644
index 0000000..3ee517b
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_5.xml.send_base
@@ -0,0 +1,15 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_5">
+    <Int8 name="i"/>
+    <Int16 name="j"/>
+    <Int32 name="k"/>
+    <Int64 name="z"/>
+    <Byte name="ui"/>
+    <UInt8 name="uii"/>
+    <UInt16 name="uj"/>
+    <UInt32 name="uk"/>
+    <UInt64 name="uz"/>
+</Dataset>
+
+Response file: test_simple_5_data.bin
diff --git a/tests/dmr-testsuite/test_simple_5.xml.trans_base b/tests/dmr-testsuite/test_simple_5.xml.trans_base
new file mode 100644
index 0000000..e3be832
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_5.xml.trans_base
@@ -0,0 +1,65 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_5">
+    <Int8 name="i"/>
+    <Int16 name="j"/>
+    <Int32 name="k"/>
+    <Int64 name="z"/>
+    <Byte name="ui"/>
+    <UInt8 name="uii"/>
+    <UInt16 name="uj"/>
+    <UInt32 name="uk"/>
+    <UInt64 name="uz"/>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_5.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_5">
+    <Int8 name="i">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>12b88320</Value>
+        </Attribute>
+    </Int8>
+    <Int16 name="j">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6f6d1f7e</Value>
+        </Attribute>
+    </Int16>
+    <Int32 name="k">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>18df6c9e</Value>
+        </Attribute>
+    </Int32>
+    <Int64 name="z">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>0c463091</Value>
+        </Attribute>
+    </Int64>
+    <Byte name="ui">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>ff000000</Value>
+        </Attribute>
+    </Byte>
+    <UInt8 name="uii">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>ff000000</Value>
+        </Attribute>
+    </UInt8>
+    <UInt16 name="uj">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>1cb109fd</Value>
+        </Attribute>
+    </UInt16>
+    <UInt32 name="uk">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>9cf92d00</Value>
+        </Attribute>
+    </UInt32>
+    <UInt64 name="uz">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>2144df1c</Value>
+        </Attribute>
+    </UInt64>
+</Dataset>
+
+The data:
+{ 127, 32000, 123456789, 72057594037927935, 255, 255, 64000, 4026531840, 18446744073709551615 }
diff --git a/tests/dmr-testsuite/test_simple_5_data.bin b/tests/dmr-testsuite/test_simple_5_data.bin
new file mode 100644
index 0000000..b4732d4
Binary files /dev/null and b/tests/dmr-testsuite/test_simple_5_data.bin differ
diff --git a/tests/dmr-testsuite/test_simple_6.1.xml b/tests/dmr-testsuite/test_simple_6.1.xml
new file mode 100644
index 0000000..9f232b1
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_6.1.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_6" dapVersion="4.0" dmrVersion="1.0"
+  xml:base="file:dap4/test_simple_6.xml" xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <Structure name="s">
+    <Int32 name="i1"/>
+    <String name="s"/>
+    <Structure name="inner">
+      <Int32 name="i2"/>
+    </Structure>
+  </Structure>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_6.1.xml.1.trans_base b/tests/dmr-testsuite/test_simple_6.1.xml.1.trans_base
new file mode 100644
index 0000000..457c089
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_6.1.xml.1.trans_base
@@ -0,0 +1,26 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Structure name="inner">
+            <Int32 name="i2"/>
+        </Structure>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Structure name="inner">
+            <Int32 name="i2"/>
+        </Structure>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>18df6c9e</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { { 123456789 } } }
diff --git a/tests/dmr-testsuite/test_simple_6.xml b/tests/dmr-testsuite/test_simple_6.xml
new file mode 100644
index 0000000..109a06c
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_6.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_6" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_6.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Structure>
+      
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_6.xml.1.trans_base b/tests/dmr-testsuite/test_simple_6.xml.1.trans_base
new file mode 100644
index 0000000..b28256d
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_6.xml.1.trans_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>196bdc9a</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { 123456789, "Silly test string: 1" } }
diff --git a/tests/dmr-testsuite/test_simple_6.xml.2.trans_base b/tests/dmr-testsuite/test_simple_6.xml.2.trans_base
new file mode 100644
index 0000000..77afc2a
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_6.xml.2.trans_base
@@ -0,0 +1,21 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>18df6c9e</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { 123456789 } }
diff --git a/tests/dmr-testsuite/test_simple_6.xml.3.trans_base b/tests/dmr-testsuite/test_simple_6.xml.3.trans_base
new file mode 100644
index 0000000..583ebd8
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_6.xml.3.trans_base
@@ -0,0 +1,21 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <String name="s"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>3d9a4edd</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { "Silly test string: 1" } }
diff --git a/tests/dmr-testsuite/test_simple_6.xml.baseline b/tests/dmr-testsuite/test_simple_6.xml.baseline
new file mode 100644
index 0000000..235fb0d
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_6.xml.baseline
@@ -0,0 +1,9 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Structure>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_6.xml.trans_base b/tests/dmr-testsuite/test_simple_6.xml.trans_base
new file mode 100644
index 0000000..b28256d
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_6.xml.trans_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_6.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_6">
+    <Structure name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>196bdc9a</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { 123456789, "Silly test string: 1" } }
diff --git a/tests/dmr-testsuite/test_simple_7.xml b/tests/dmr-testsuite/test_simple_7.xml
new file mode 100644
index 0000000..57daf12
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_7.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_7" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_7.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Sequence>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_7.xml.1.trans_base b/tests/dmr-testsuite/test_simple_7.xml.1.trans_base
new file mode 100644
index 0000000..af9fe17
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_7.xml.1.trans_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b617a898</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ { { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } } }
diff --git a/tests/dmr-testsuite/test_simple_7.xml.2.trans_base b/tests/dmr-testsuite/test_simple_7.xml.2.trans_base
new file mode 100644
index 0000000..306fd93
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_7.xml.2.trans_base
@@ -0,0 +1,21 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b2871a70</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ { { 123456789 }, { 123456789 }, { 123456789 }, { 123456789 } } }
diff --git a/tests/dmr-testsuite/test_simple_7.xml.baseline b/tests/dmr-testsuite/test_simple_7.xml.baseline
new file mode 100644
index 0000000..05c945a
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_7.xml.baseline
@@ -0,0 +1,9 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_7.xml.trans_base b/tests/dmr-testsuite/test_simple_7.xml.trans_base
new file mode 100644
index 0000000..af9fe17
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_7.xml.trans_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+    </Sequence>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_7.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_7">
+    <Sequence name="s">
+        <Int32 name="i1"/>
+        <String name="s"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b617a898</Value>
+        </Attribute>
+    </Sequence>
+</Dataset>
+
+The data:
+{ { { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } } }
diff --git a/tests/dmr-testsuite/test_simple_8.1.xml b/tests/dmr-testsuite/test_simple_8.1.xml
new file mode 100644
index 0000000..f851830
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_8.1.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_8.1" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_8.1.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Sequence name="outer">
+    <Float32 name="x"/>
+    <Float32 name="y"/>
+    <Sequence name="inner">
+      <Int32 name="i1"/>
+      <String name="s"/>
+    </Sequence>    
+  </Sequence>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_8.xml b/tests/dmr-testsuite/test_simple_8.xml
new file mode 100644
index 0000000..c66edaf
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_8.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_8" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_8.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Structure name="outer">
+    <Sequence name="s">
+      <Int32 name="i1"/>
+      <String name="s"/>
+    </Sequence>    
+  </Structure>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_8.xml.1.trans_base b/tests/dmr-testsuite/test_simple_8.xml.1.trans_base
new file mode 100644
index 0000000..3ddf2c9
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_8.xml.1.trans_base
@@ -0,0 +1,26 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_8">
+    <Structure name="outer">
+        <Sequence name="s">
+            <Int32 name="i1"/>
+            <String name="s"/>
+        </Sequence>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_8">
+    <Structure name="outer">
+        <Sequence name="s">
+            <Int32 name="i1"/>
+            <String name="s"/>
+        </Sequence>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b617a898</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { { { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } } } }
diff --git a/tests/dmr-testsuite/test_simple_8.xml.2.trans_base b/tests/dmr-testsuite/test_simple_8.xml.2.trans_base
new file mode 100644
index 0000000..7dec4b0
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_8.xml.2.trans_base
@@ -0,0 +1,25 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_8">
+    <Structure name="outer">
+        <Sequence name="s">
+            <Int32 name="i1"/>
+            <String name="s"/>
+        </Sequence>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_8">
+    <Structure name="outer">
+        <Sequence name="s">
+            <String name="s"/>
+        </Sequence>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>03a807fd</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { { { "Silly test string: 1" }, { "Silly test string: 1" }, { "Silly test string: 1" }, { "Silly test string: 1" } } } }
diff --git a/tests/dmr-testsuite/test_simple_8.xml.baseline b/tests/dmr-testsuite/test_simple_8.xml.baseline
new file mode 100644
index 0000000..c3bd020
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_8.xml.baseline
@@ -0,0 +1,11 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_8">
+    <Structure name="outer">
+        <Sequence name="s">
+            <Int32 name="i1"/>
+            <String name="s"/>
+        </Sequence>
+    </Structure>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_8.xml.trans_base b/tests/dmr-testsuite/test_simple_8.xml.trans_base
new file mode 100644
index 0000000..3ddf2c9
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_8.xml.trans_base
@@ -0,0 +1,26 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_8">
+    <Structure name="outer">
+        <Sequence name="s">
+            <Int32 name="i1"/>
+            <String name="s"/>
+        </Sequence>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_8.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_8">
+    <Structure name="outer">
+        <Sequence name="s">
+            <Int32 name="i1"/>
+            <String name="s"/>
+        </Sequence>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>b617a898</Value>
+        </Attribute>
+    </Structure>
+</Dataset>
+
+The data:
+{ { { { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" }, { 123456789, "Silly test string: 1" } } } }
diff --git a/tests/dmr-testsuite/test_simple_9.1.xml b/tests/dmr-testsuite/test_simple_9.1.xml
new file mode 100644
index 0000000..cd2c01e
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_9.1.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_9" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_9.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Enumeration name="color" basetype="Int32">
+    <EnumConst name="red" value="100"/>
+    <EnumConst name="blue" value="200"/>
+    <EnumConst name="gray" value="300"/>
+  </Enumeration>
+  
+  <Enumeration name="shade" basetype="UInt64">
+    <EnumConst name="light" value="1"/>
+    <EnumConst name="med" value="2"/>
+    <EnumConst name="dark" value="3"/>
+    
+    <EnumConst name="pitch" value="256"/>
+  </Enumeration>
+  
+  <Enum name="e" enum="color"/>
+  <Enum name="f" enum="shade"/>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_9.1.xml.baseline b/tests/dmr-testsuite/test_simple_9.1.xml.baseline
new file mode 100644
index 0000000..9f4c831
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_9.1.xml.baseline
@@ -0,0 +1,18 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_9.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_9">
+    <Enumeration name="color" basetype="Int32">
+        <EnumConst name="red" value="100"/>
+        <EnumConst name="blue" value="200"/>
+        <EnumConst name="gray" value="300"/>
+    </Enumeration>
+    <Enumeration name="shade" basetype="UInt64">
+        <EnumConst name="light" value="1"/>
+        <EnumConst name="med" value="2"/>
+        <EnumConst name="dark" value="3"/>
+        <EnumConst name="pitch" value="256"/>
+    </Enumeration>
+    <Enum name="e" enum="/color"/>
+    <Enum name="f" enum="/shade"/>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_9.1.xml.trans_base b/tests/dmr-testsuite/test_simple_9.1.xml.trans_base
new file mode 100644
index 0000000..260bab2
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_9.1.xml.trans_base
@@ -0,0 +1,45 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_9.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_9">
+    <Enumeration name="color" basetype="Int32">
+        <EnumConst name="red" value="100"/>
+        <EnumConst name="blue" value="200"/>
+        <EnumConst name="gray" value="300"/>
+    </Enumeration>
+    <Enumeration name="shade" basetype="UInt64">
+        <EnumConst name="light" value="1"/>
+        <EnumConst name="med" value="2"/>
+        <EnumConst name="dark" value="3"/>
+        <EnumConst name="pitch" value="256"/>
+    </Enumeration>
+    <Enum name="e" enum="/color"/>
+    <Enum name="f" enum="/shade"/>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_9.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_9">
+    <Enumeration name="color" basetype="Int32">
+        <EnumConst name="red" value="100"/>
+        <EnumConst name="blue" value="200"/>
+        <EnumConst name="gray" value="300"/>
+    </Enumeration>
+    <Enumeration name="shade" basetype="UInt64">
+        <EnumConst name="light" value="1"/>
+        <EnumConst name="med" value="2"/>
+        <EnumConst name="dark" value="3"/>
+        <EnumConst name="pitch" value="256"/>
+    </Enumeration>
+    <Enum name="e" enum="/color">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>99f8b879</Value>
+        </Attribute>
+    </Enum>
+    <Enum name="f" enum="/shade">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>a988dff7</Value>
+        </Attribute>
+    </Enum>
+</Dataset>
+
+The data:
+{ 1, 1 }
diff --git a/tests/dmr-testsuite/test_simple_9.2.xml b/tests/dmr-testsuite/test_simple_9.2.xml
new file mode 100644
index 0000000..440507e
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_9.2.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_9" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_9.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Enumeration name="color" basetype="Int32">
+    <EnumConst name="red" value="100"/>
+    <EnumConst name="blue" value="200"/>
+    <EnumConst name="gray" value="300"/>
+  </Enumeration>
+  
+  <Enumeration name="shade" basetype="UInt64">
+    <EnumConst name="light" value="1"/>
+    <EnumConst name="med" value="2"/>
+    <EnumConst name="dark" value="3"/>
+    
+    <EnumConst name="pitch" value="256"/>
+  </Enumeration>
+  
+  <Enum name="e" enum="color"/>
+  <Enum name="f" enum="shade"/>
+
+  <Int32 name="a"/>  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_9.xml b/tests/dmr-testsuite/test_simple_9.xml
new file mode 100644
index 0000000..1760558
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_9.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Dataset name="test_simple_9" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/test_simple_9.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Enumeration name="color" basetype="Byte">
+    <EnumConst name="red" value="1"/>
+    <EnumConst name="blue" value="2"/>
+    <EnumConst name="gray" value="3"/>
+  </Enumeration>
+  
+  <Enum name="e" enum="color"/>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/test_simple_9.xml.baseline b/tests/dmr-testsuite/test_simple_9.xml.baseline
new file mode 100644
index 0000000..9e02ef8
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_9.xml.baseline
@@ -0,0 +1,11 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_9.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_9">
+    <Enumeration name="color" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="blue" value="2"/>
+        <EnumConst name="gray" value="3"/>
+    </Enumeration>
+    <Enum name="e" enum="/color"/>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/test_simple_9.xml.trans_base b/tests/dmr-testsuite/test_simple_9.xml.trans_base
new file mode 100644
index 0000000..ee8aa87
--- /dev/null
+++ b/tests/dmr-testsuite/test_simple_9.xml.trans_base
@@ -0,0 +1,27 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_9.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_9">
+    <Enumeration name="color" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="blue" value="2"/>
+        <EnumConst name="gray" value="3"/>
+    </Enumeration>
+    <Enum name="e" enum="/color"/>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/test_simple_9.xml" dapVersion="4.0" dmrVersion="1.0" name="test_simple_9">
+    <Enumeration name="color" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="blue" value="2"/>
+        <EnumConst name="gray" value="3"/>
+    </Enumeration>
+    <Enum name="e" enum="/color">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>a505df1b</Value>
+        </Attribute>
+    </Enum>
+</Dataset>
+
+The data:
+{ 1 }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml b/tests/dmr-testsuite/vol_1_ce_1.xml
new file mode 100644
index 0000000..cf5025d
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- This is the DMR used for the first example in the CE section of the DAP4 spec. jhrg 12/30/13 -->
+
+<Dataset name="vol_1_ce_1" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_1.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#"
+  xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+
+  <Int32 name="u"/>
+  <Int32 name="v"/>
+  <Structure name="Point">
+    <Int32 name="x"/>
+    <Int32 name="y"/>
+  </Structure>
+
+</Dataset>
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.1.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.1.func_base
new file mode 100644
index 0000000..f5705e4
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.1.func_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="u">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>8f450c0e</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ 1234567890 }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.10.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.10.func_base
new file mode 100644
index 0000000..36d678c
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.10.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>85b447dc</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {10, 20, 30, -40} }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.11.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.11.func_base
new file mode 100644
index 0000000..ee37ffc
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.11.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>680cc4fc</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {10, 20, 30, 40} }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.12.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.12.func_base
new file mode 100644
index 0000000..36d678c
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.12.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>85b447dc</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {10, 20, 30, -40} }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.13.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.13.func_base
new file mode 100644
index 0000000..7771aba
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.13.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>cb9ac07d</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {1, 2, 3, 1.84467440737096e+19} }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.14.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.14.func_base
new file mode 100644
index 0000000..2e352a7
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.14.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>8158d22c</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {1, 2, 3, 9.22337203685478e+18} }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.15.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.15.func_base
new file mode 100644
index 0000000..8781880
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.15.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>ab75a7bc</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {10, 20, 30, 45.5000019073486} }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.16.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.16.func_base
new file mode 100644
index 0000000..f404ccc
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.16.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>cb95303e</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {10, 20, 30, 45.5} }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.2.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.2.func_base
new file mode 100644
index 0000000..c6eebd1
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.2.func_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="u">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>fe284a6e</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ 1.52415787501905e+16 }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.3.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.3.func_base
new file mode 100644
index 0000000..30d0674
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.3.func_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="u">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>bb61bad1</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ 12345678.9 }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.4.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.4.func_base
new file mode 100644
index 0000000..29b1854
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.4.func_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>8f450c0e</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ 1234567890 }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.5.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.5.func_base
new file mode 100644
index 0000000..e59049f
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.5.func_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>fe284a6e</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ 1.52415787501905e+16 }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.6.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.6.func_base
new file mode 100644
index 0000000..b0880c4
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.6.func_base
@@ -0,0 +1,22 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="x">
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>bb61bad1</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ 12345678.9 }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.7.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.7.func_base
new file mode 100644
index 0000000..ee37ffc
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.7.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>680cc4fc</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {10, 20, 30, 40} }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.8.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.8.func_base
new file mode 100644
index 0000000..204c102
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.8.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>3fca0d88</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {100, 110, 120, -90} }
diff --git a/tests/dmr-testsuite/vol_1_ce_1.xml.9.func_base b/tests/dmr-testsuite/vol_1_ce_1.xml.9.func_base
new file mode 100644
index 0000000..ee37ffc
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_1.xml.9.func_base
@@ -0,0 +1,23 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_1.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_1">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+        <Int32 name="x"/>
+        <Int32 name="y"/>
+    </Structure>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="g1">
+        <Dim size="4"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>680cc4fc</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {10, 20, 30, 40} }
diff --git a/tests/dmr-testsuite/vol_1_ce_10.xml b/tests/dmr-testsuite/vol_1_ce_10.xml
new file mode 100644
index 0000000..c9eff94
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_10.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 1/2/14 -->
+
+<Dataset name="vol_1_ce_10" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_10.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  <Float32 name="lat">
+    <Dim size="100"/>
+    <Dim size="50"/>
+  </Float32>
+  
+  <Float32 name="lon">
+    <Dim size="100"/>
+    <Dim size="50"/>
+  </Float32>
+  
+  <Float32 name="temp">
+    <Dim size="100"/>
+    <Dim size="50"/>
+  </Float32>
+</Dataset>
diff --git a/tests/dmr-testsuite/vol_1_ce_10.xml.1.func_base b/tests/dmr-testsuite/vol_1_ce_10.xml.1.func_base
new file mode 100644
index 0000000..5e167e8
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_10.xml.1.func_base
@@ -0,0 +1,30 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_10.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_10">
+    <Float32 name="lat">
+        <Dim size="100"/>
+        <Dim size="50"/>
+    </Float32>
+    <Float32 name="lon">
+        <Dim size="100"/>
+        <Dim size="50"/>
+    </Float32>
+    <Float32 name="temp">
+        <Dim size="100"/>
+        <Dim size="50"/>
+    </Float32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="lat">
+        <Dim size="100"/>
+        <Dim size="50"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6ba82768</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {{999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 99 [...]
diff --git a/tests/dmr-testsuite/vol_1_ce_10.xml.2.func_base b/tests/dmr-testsuite/vol_1_ce_10.xml.2.func_base
new file mode 100644
index 0000000..5bd2d3d
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_10.xml.2.func_base
@@ -0,0 +1,37 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_10.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_10">
+    <Float32 name="lat">
+        <Dim size="100"/>
+        <Dim size="50"/>
+    </Float32>
+    <Float32 name="lon">
+        <Dim size="100"/>
+        <Dim size="50"/>
+    </Float32>
+    <Float32 name="temp">
+        <Dim size="100"/>
+        <Dim size="50"/>
+    </Float32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="lat">
+        <Dim size="100"/>
+        <Dim size="50"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6ba82768</Value>
+        </Attribute>
+    </Float64>
+    <Float64 name="lon">
+        <Dim size="100"/>
+        <Dim size="50"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>6ba82768</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {{999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 999.990005493164, 99 [...]
diff --git a/tests/dmr-testsuite/vol_1_ce_10.xml.3.func_base b/tests/dmr-testsuite/vol_1_ce_10.xml.3.func_base
new file mode 100644
index 0000000..60468dc
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_10.xml.3.func_base
@@ -0,0 +1,37 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_10.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_10">
+    <Float32 name="lat">
+        <Dim size="100"/>
+        <Dim size="50"/>
+    </Float32>
+    <Float32 name="lon">
+        <Dim size="100"/>
+        <Dim size="50"/>
+    </Float32>
+    <Float32 name="temp">
+        <Dim size="100"/>
+        <Dim size="50"/>
+    </Float32>
+</Dataset>
+
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="function_results">
+    <Float64 name="lat">
+        <Dim size="2"/>
+        <Dim size="2"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>8486a6d6</Value>
+        </Attribute>
+    </Float64>
+    <Float64 name="lon">
+        <Dim size="2"/>
+        <Dim size="2"/>
+        <Attribute name="DAP4_Checksum_CRC32" type="String">
+            <Value>8486a6d6</Value>
+        </Attribute>
+    </Float64>
+</Dataset>
+
+The data:
+{ {{999.990005493164, 999.990005493164},{999.990005493164, 999.990005493164}}, {{999.990005493164, 999.990005493164},{999.990005493164, 999.990005493164}} }
diff --git a/tests/dmr-testsuite/vol_1_ce_11.xml b/tests/dmr-testsuite/vol_1_ce_11.xml
new file mode 100644
index 0000000..b7cb18a
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_11.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 1/2/14 -->
+
+<Dataset name="vol_1_ce_11" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_11.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  <Dimension name="nlat" size="100"/>
+  <Dimension name="nlon" size="50"/>
+  
+  <Float32 name="lat">
+    <Dim name="nlat"/>
+  </Float32>
+  <Float32 name="lon">
+    <Dim name="nlon"/>
+  </Float32>
+  
+  <Float32 name="temp">
+    <Dim name="nlon"/>
+    <Dim name="nlat"/>
+    <Map name="lon"/>
+    <Map name="lat"/>
+  </Float32>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/vol_1_ce_12.xml b/tests/dmr-testsuite/vol_1_ce_12.xml
new file mode 100644
index 0000000..1023709
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_12.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 1/2/14 -->
+
+<Dataset name="vol_1_ce_12" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_12.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  <Dimension name="x" size="100"/>
+  <Dimension name="y" size="50"/>
+  
+  <Float32 name="lat">
+    <Dim name="x"/>
+    <Dim name="y"/>
+  </Float32>
+  <Float32 name="lon">
+    <Dim name="x"/>
+    <Dim name="y"/>
+  </Float32>
+  
+  <Float32 name="temp">
+    <Dim name="x"/>
+    <Dim name="y"/>
+    <Map name="lon"/>
+    <Map name="lat"/>
+  </Float32>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/vol_1_ce_2.xml b/tests/dmr-testsuite/vol_1_ce_2.xml
new file mode 100644
index 0000000..c598cc4
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_2.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 12/30/13 -->
+
+<Dataset name="vol_1_ce_2" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_2.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Int32 name="u"/>
+  <Int32 name="v"/>
+  <Group name="inst2">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Structure name="Point">
+      <Int32 name="x"/>
+      <Int32 name="y"/>
+    </Structure>
+  </Group>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/vol_1_ce_2.xml.1.func_base b/tests/dmr-testsuite/vol_1_ce_2.xml.1.func_base
new file mode 100644
index 0000000..5d726d6
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_2.xml.1.func_base
@@ -0,0 +1,15 @@
+Parse successful
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:dap4/vol_1_ce_2.xml" dapVersion="4.0" dmrVersion="1.0" name="vol_1_ce_2">
+    <Int32 name="u"/>
+    <Int32 name="v"/>
+    <Group name="inst2">
+        <Int32 name="u"/>
+        <Int32 name="v"/>
+        <Structure name="Point">
+            <Int32 name="x"/>
+            <Int32 name="y"/>
+        </Structure>
+    </Group>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/vol_1_ce_3.xml b/tests/dmr-testsuite/vol_1_ce_3.xml
new file mode 100644
index 0000000..db4e968
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_3.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 12/30/13 -->
+
+<Dataset name="vol_1_ce_3" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_3.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Int32 name="u">
+    <Dim size="256"/>
+    <Dim size="256"/>
+  </Int32>
+  <Int32 name="v">
+    <Dim size="256"/>
+    <Dim size="256"/>
+  </Int32>
+  <Structure name="Point">
+    <Int32 name="x"/>
+    <Int32 name="y"/>
+    <Dim size="256"/>
+  </Structure>
+</Dataset>
+
diff --git a/tests/dmr-testsuite/vol_1_ce_4.xml b/tests/dmr-testsuite/vol_1_ce_4.xml
new file mode 100644
index 0000000..10678a0
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_4.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 12/30/13 -->
+
+<Dataset name="vol_1_ce_4" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_4.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  <Int32 name="u">
+    <Dim size="256"/>
+    <Dim size="1024"/>
+  </Int32>
+  <Structure name="Point">
+    <Int32 name="x"/>
+    <Int32 name="y">
+      <Dim size="256"/>
+    </Int32>
+    <Int32 name="z">
+      <Dim size="1024"/>
+    </Int32>
+    <Dim size="256"/>
+  </Structure>
+</Dataset>
+
+
diff --git a/tests/dmr-testsuite/vol_1_ce_5.xml b/tests/dmr-testsuite/vol_1_ce_5.xml
new file mode 100644
index 0000000..3e33909
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_5.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 12/31/13 -->
+
+<Dataset name="vol_1_ce_5" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_5.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  <Int32 name="u">
+    <Dim size="256"/>
+    <Dim size="1024"/>
+  </Int32>
+  <Structure name="Points">
+    <Int32 name="x"/>
+    <Int32 name="y"/>
+    <Structure name="sounding">
+      <Int32 name="height">
+        <Dim size="1024"/>
+      </Int32>
+      <Int32 name="pressure">
+        <Dim size="1024"/>
+      </Int32>
+    </Structure>
+    
+    <Dim size="256"/>
+  </Structure>
+</Dataset>
+
+
diff --git a/tests/dmr-testsuite/vol_1_ce_6.xml b/tests/dmr-testsuite/vol_1_ce_6.xml
new file mode 100644
index 0000000..599bdb6
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_6.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 12/31/13 -->
+
+<Dataset name="vol_1_ce_6" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_6.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  <Sequence name="s1">
+    <Int32 name="x"/>
+    <Int32 name="y"/>
+  </Sequence>
+  
+  <Sequence name="s2">
+    <Int32 name="x"/>
+    <Int32 name="y"/>
+    <Dim size="100"/>
+  </Sequence>
+  
+  <Sequence name="s3">
+    <Int32 name="z"/>
+    <Int32 name="x">
+      <Dim size="10"/>
+    </Int32>
+  </Sequence>
+  
+  <Sequence name="s4">
+    <Int32 name="z"/>
+    <Int32 name="x">
+      <Dim size="1024"/>
+    </Int32>
+    <Dim size="100"/>
+  </Sequence>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/vol_1_ce_7.xml b/tests/dmr-testsuite/vol_1_ce_7.xml
new file mode 100644
index 0000000..24acc73
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_7.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 12/31/13 -->
+
+<Dataset name="vol_1_ce_7" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_7.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  <Dimension name="nlat" size="100"/>
+  <Dimension name="nlon" size="50"/>
+  
+  <Float32 name="lat">
+    <Dim name="nlat"/>
+  </Float32>
+  <Float32 name="lon">
+    <Dim name="nlon"/>
+  </Float32>
+  
+  <Float32 name="temp">
+    <Dim name="nlon"/>
+    <Dim name="nlat"/>
+    <Map name="lat"/>
+    <Map name="lon"/>
+  </Float32>
+
+  <Float32 name="sal">
+    <Dim name="nlon"/>
+    <Dim name="nlat"/>
+    <Map name="lat"/>
+    <Map name="lon"/>
+  </Float32>
+  
+  <Float32 name="O2">
+    <Dim name="nlat"/>
+    <Dim name="nlon"/>
+    <Map name="lon"/>
+    <Map name="lat"/>
+  </Float32>
+  
+  <Float32 name="CO2">
+    <Dim name="nlon"/>
+    <Dim name="nlat"/>
+    <Dim size="10"/>
+    <Map name="lat"/>
+    <Map name="lon"/>
+  </Float32>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/vol_1_ce_8.xml b/tests/dmr-testsuite/vol_1_ce_8.xml
new file mode 100644
index 0000000..c262e26
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_8.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 1/2/13 -->
+
+<Dataset name="vol_1_ce_8" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_8.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  
+  <Float32 name="temp">
+    <Dim size="10"/>
+  </Float32>
+  
+  <Float32 name="u">
+    <Dim size="256"/>
+    <Dim size="256"/>
+  </Float32>
+
+  <Float32 name="v">
+    <Dim size="256"/>
+    <Dim size="256"/>
+  </Float32>
+
+  <Sequence name="Points">
+    <Int32 name="x"/>
+    <Int32 name="y"/>
+  </Sequence>
+  
+</Dataset>
diff --git a/tests/dmr-testsuite/vol_1_ce_9.xml b/tests/dmr-testsuite/vol_1_ce_9.xml
new file mode 100644
index 0000000..cc8e0a0
--- /dev/null
+++ b/tests/dmr-testsuite/vol_1_ce_9.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Example in the CE section of the DAP4 spec. jhrg 1/2/13 -->
+
+<Dataset name="vol_1_ce_9" dapVersion="4.0" dmrVersion="1.0" xml:base="file:dap4/vol_1_ce_9.xml"
+  xmlns="http://xml.opendap.org/ns/DAP/4.0#" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+  <Sequence name="Points1">
+    <Int32 name="x">
+      <Dim size="100"/>
+    </Int32>
+    <Int32 name="y"/>
+  </Sequence>
+  
+  <Sequence name="Points2">
+    <Int32 name="x"/>
+    <Int32 name="y"/>
+    <Sequence name="sounding">
+      <Int32 name="depth"/>
+      <Int32 name="temp"/>
+      <Dim size="20"/>
+    </Sequence>
+  </Sequence>
+  
+  <Structure name="Points3">
+    <Int32 name="x"/>
+    <Int32 name="y"/>
+    <Sequence name="raw">
+      <Int32 name="depth"/>
+      <Int32 name="temps">
+        <Dim size="4"/>
+      </Int32>
+      <Dim size="300"/>
+    </Sequence>
+  </Structure>
+  
+</Dataset>
diff --git a/tests/expr-test.cc b/tests/expr-test.cc
index 278fc5d..e065783 100644
--- a/tests/expr-test.cc
+++ b/tests/expr-test.cc
@@ -55,6 +55,7 @@
 #include "DDS.h"
 #include "DataDDS.h"
 #include "ConstraintEvaluator.h"
+#include "ServerFunctionsList.h"
 #include "XDRStreamUnMarshaller.h"
 #include "XDRStreamMarshaller.h"
 #include "ResponseBuilder.h"
@@ -66,13 +67,13 @@
 #include "TestCommon.h"
 #include "TestTypeFactory.h"
 
+#include "TestFunction.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;
@@ -162,7 +163,10 @@ int main(int argc, char *argv[])
     string constraint = "";
     TestTypeFactory ttf;
     DDS table(&ttf);
-    ConstraintEvaluator eval;
+
+    // Load our one server function...
+    ServerFunction *scale = new TestFunction;
+    ServerFunctionsList::TheList()->add_function(scale);
 
     // process options
 
@@ -241,6 +245,8 @@ int main(int argc, char *argv[])
         }
 
         if (parser_test) {
+            ConstraintEvaluator eval;
+
             test_parser(eval, table, dds_file_name, constraint);
         }
 
@@ -249,12 +255,10 @@ int main(int argc, char *argv[])
         }
 
         if (whole_enchalada) {
-            constrained_trans(dds_file_name, constraint_expr, constraint,
-                              series_values);
+            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);
+            intern_data_test(dds_file_name, constraint_expr, constraint, series_values);
         }
     }
     catch(Error & e) {
@@ -483,8 +487,7 @@ constrained_trans(const string & dds_name, const bool constraint_expr,
         char c[256];
         cin.getline(c, 256);
         if (!cin) {
-            throw InternalErr(__FILE__, __LINE__,
-                              "Could not read the constraint expression\n");
+            throw InternalErr(__FILE__, __LINE__, "Could not read the constraint expression\n");
         }
         ce = c;
     }
diff --git a/tests/expr-testsuite/test.5.func3.base b/tests/expr-testsuite/test.5.func3.base
new file mode 100644
index 0000000..9a38843
--- /dev/null
+++ b/tests/expr-testsuite/test.5.func3.base
@@ -0,0 +1,16 @@
+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:
+Float64 i[1] = {246913578};
diff --git a/tests/expr-testsuite/test.5.func4.base b/tests/expr-testsuite/test.5.func4.base
new file mode 100644
index 0000000..9c421ae
--- /dev/null
+++ b/tests/expr-testsuite/test.5.func4.base
@@ -0,0 +1,16 @@
+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:
+Float64 j = 246913578;
diff --git a/tests/expr-testsuite/test.6.func1.base b/tests/expr-testsuite/test.6.func1.base
new file mode 100644
index 0000000..383dd3e
--- /dev/null
+++ b/tests/expr-testsuite/test.6.func1.base
@@ -0,0 +1,7 @@
+The complete DDS:
+Dataset {
+    Int32 i[20][10];
+    String s;
+} test1;
+The data:
+Float64 i[20][10] = {{246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578},{246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578},{246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578},{246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578, 246913578},{246913578, 246913578, 2469 [...]
diff --git a/tests/expr-testsuite/test.6.func2.base b/tests/expr-testsuite/test.6.func2.base
new file mode 100644
index 0000000..8fbcb10
--- /dev/null
+++ b/tests/expr-testsuite/test.6.func2.base
@@ -0,0 +1,7 @@
+The complete DDS:
+Dataset {
+    Int32 i[20][10];
+    String s;
+} test1;
+The data:
+Float64 i[3][4] = {{246913578, 246913578, 246913578, 246913578},{246913578, 246913578, 246913578, 246913578},{246913578, 246913578, 246913578, 246913578}};
diff --git a/tests/expr-testsuite/test.6.func3.base b/tests/expr-testsuite/test.6.func3.base
new file mode 100644
index 0000000..8e2ed78
--- /dev/null
+++ b/tests/expr-testsuite/test.6.func3.base
@@ -0,0 +1,14 @@
+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;
diff --git a/tests/expr-testsuite/test.f b/tests/expr-testsuite/test.f
new file mode 100644
index 0000000..990596d
--- /dev/null
+++ b/tests/expr-testsuite/test.f
@@ -0,0 +1,9 @@
+# Test Sequences
+
+Dataset {
+   Sequence {
+      Structure {
+          UInt32 i;
+      } inner;
+   } names;
+} test.e;
diff --git a/tests/expr-testsuite/test.fa.base b/tests/expr-testsuite/test.fa.base
new file mode 100644
index 0000000..2037ddc
--- /dev/null
+++ b/tests/expr-testsuite/test.fa.base
@@ -0,0 +1,14 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Structure {
+            UInt32 i;
+        } inner;
+    } names;
+} test.e;
+The data:
+Sequence {
+    Structure {
+        UInt32 i;
+    } inner;
+} names = { { { 32 } }, { { 1024 } }, { { 32768 } }, { { 1048576 } } };
diff --git a/tests/expr-testsuite/test.fb.base b/tests/expr-testsuite/test.fb.base
new file mode 100644
index 0000000..17e3136
--- /dev/null
+++ b/tests/expr-testsuite/test.fb.base
@@ -0,0 +1,14 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Structure {
+            UInt32 i;
+        } inner;
+    } names;
+} test.e;
+The data:
+Sequence {
+    Structure {
+        UInt32 i;
+    } inner;
+} names = { { { 32 } }, { { 1024 } } };
diff --git a/tests/getdap-testsuite/fnoc1.nc.dds b/tests/getdap-testsuite/fnoc1.nc.dds
new file mode 100644
index 0000000..8c41e1b
--- /dev/null
+++ b/tests/getdap-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/getdapTest b/tests/getdapTest
new file mode 100755
index 0000000..efb4662
--- /dev/null
+++ b/tests/getdapTest
@@ -0,0 +1,2034 @@
+#! /bin/sh
+# Generated from getdapTest.at by GNU Autoconf 2.69.
+#
+# Copyright (C) 2009-2012 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.
+as_myself=
+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
+test -x / || 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 :
+  export CONFIG_SHELL
+             # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+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_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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 to rerun failed tests.
+at_recheck=
+# 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
+
+# Whether to enable colored test results.
+at_color=no
+# List of the tested programs.
+at_tested=''
+# 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;getdapTest.at:34;getdap -d http://test.opendap.org/dap/data/nc/fnoc1.nc getdap-testsuite/fnoc1.nc.dds (pass);getdap;
+"
+# List of the all the test groups.
+at_groups_all=`$as_echo "$at_help_all" | sed 's/;.*//'`
+
+# 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 1; 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" : '[^=]*=\(.*\)'` ;;
+  *)    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=:
+	;;
+
+    --color )
+	at_color=always
+	;;
+    --color=* )
+	case $at_optarg in
+	no | never | none) at_color=never ;;
+	auto | tty | if-tty) at_color=auto ;;
+	always | yes | force) at_color=always ;;
+	*) at_optname=`echo " $at_option" | sed 's/^ //; s/=.*//'`
+	   as_fn_error $? "unrecognized argument to $at_optname: $at_optarg" ;;
+	esac
+	;;
+
+    --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$as_nl"
+	;;
+
+    # 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 -ne '/^'$at_range_start'$/,$p'`
+	as_fn_append at_groups "$at_range$as_nl"
+	;;
+
+    -[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 -ne '1,/^'$at_range_end'$/p'`
+	as_fn_append at_groups "$at_range$as_nl"
+	;;
+
+    [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 -ne '/^'$at_range_start'$/,/^'$at_range_end'$/p'`
+	as_fn_append at_groups "$at_range$as_nl"
+	;;
+
+    # Directory selection.
+    --directory | -C )
+	at_prev=--directory
+	;;
+    --directory=* )
+	at_change_dir=:
+	at_dir=$at_optarg
+	if test x- = "x$at_dir" ; then
+	  at_dir=./-
+	fi
+	;;
+
+    # 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 keywords.
+	at_groups_selected=`$as_echo "$at_groups_selected" | sed 's/;.*//'`
+	as_fn_append at_groups "$at_groups_selected$as_nl"
+	;;
+    --recheck)
+	at_recheck=:
+	;;
+
+    *=*)
+	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
+
+# The file containing the suite.
+at_suite_log=$at_dir/$as_me.log
+
+# Selected test groups.
+if test -z "$at_groups$at_recheck"; then
+  at_groups=$at_groups_all
+else
+  if test -n "$at_recheck" && test -r "$at_suite_log"; then
+    at_oldfails=`sed -n '
+      /^Failed tests:$/,/^Skipped tests:$/{
+	s/^[ ]*\([1-9][0-9]*\):.*/\1/p
+      }
+      /^Unexpected passes:$/,/^## Detailed failed tests/{
+	s/^[ ]*\([1-9][0-9]*\):.*/\1/p
+      }
+      /^## Detailed failed tests/q
+      ' "$at_suite_log"`
+    as_fn_append at_groups "$at_oldfails$as_nl"
+  fi
+  # Sort the tests, removing duplicates.
+  at_groups=`$as_echo "$at_groups" | sort -nu | sed '/^$/d'`
+fi
+
+if test x"$at_color" = xalways \
+   || { test x"$at_color" = xauto && test -t 1; }; then
+  at_red=`printf '\033[0;31m'`
+  at_grn=`printf '\033[0;32m'`
+  at_lgn=`printf '\033[1;32m'`
+  at_blu=`printf '\033[1;34m'`
+  at_std=`printf '\033[m'`
+else
+  at_red= at_grn= at_lgn= at_blu= at_std=
+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
+      --color[=never|auto|always]
+                 enable colored test results on terminal, or always
+  -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
+      --recheck  select all tests that failed or passed unexpectedly last time
+  -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.14.0 test suite: getdap test groups:
+
+ NUM: FILE-NAME:LINE     TEST-GROUP-NAME
+      KEYWORDS
+
+_ATEOF
+  # Pass an empty line as separator between selected groups and help.
+  $as_echo "$at_groups$as_nl$as_nl$at_help_all" |
+    awk 'NF == 1 && FS != ";" {
+	   selected[$ 1] = 1
+	   next
+	 }
+	 /^$/ { FS = ";" }
+	 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.14.0)" &&
+  cat <<\_ATEOF || at_write_fail=1
+
+Copyright (C) 2012 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?  Yes if more than one test is run.
+case $at_groups in #(
+  *$as_nl* )
+      at_print_banners=: ;; #(
+  * ) at_print_banners=false ;;
+esac
+# Text for banner N, set to a single space once printed.
+
+# Take any -C into account.
+if $at_change_dir ; then
+  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_dir might have changed since earlier).
+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.
+$as_echo "## --------------------------------- ##
+## libdap 3.14.0 test suite: getdap. ##
+## --------------------------------- ##"
+{
+  $as_echo "## --------------------------------- ##
+## libdap 3.14.0 test suite: getdap. ##
+## --------------------------------- ##"
+  echo
+
+  $as_echo "$as_me: command line was:"
+  $as_echo "  \$ $0 $at_cli_args"
+  echo
+
+  # If ChangeLog exists, list a few lines in case it might help determining
+  # the exact version.
+  if test -n "$at_top_srcdir" && test -f "$at_top_srcdir/ChangeLog"; then
+    $as_echo "## ---------- ##
+## ChangeLog. ##
+## ---------- ##"
+    echo
+    sed 's/^/| /;10q' "$at_top_srcdir/ChangeLog"
+    echo
+  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=\" \""
+  if test -z "$at_banner_text"; then
+    $at_first || echo
+  else
+    $as_echo "$as_nl$at_banner_text$as_nl"
+  fi
+} # 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. ##
+## -------------------------------- ##
+{
+  $as_echo "## ---------------- ##
+## Tested programs. ##
+## ---------------- ##"
+  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/getdapTest.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
+
+{
+  $as_echo "## ------------------ ##
+## Running the tests. ##
+## ------------------ ##"
+} >&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 for 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_banner ORDINAL LINE DESC PAD [BANNER]
+# -------------------------------------------------
+# Declare the test group ORDINAL, located at LINE with group description DESC,
+# and residing under BANNER. Use PAD to align the status column.
+at_fn_group_banner ()
+{
+  at_setup_line="$2"
+  test -n "$5" && at_fn_banner $5
+  at_desc="$3"
+  case $1 in
+    [0-9])      at_desc_line="  $1: ";;
+    [0-9][0-9]) at_desc_line=" $1: " ;;
+    *)          at_desc_line="$1: "  ;;
+  esac
+  as_fn_append at_desc_line "$3$4"
+  $at_quiet $as_echo_n "$at_desc_line"
+  echo "#                             -*- compilation -*-" >> "$at_group_log"
+}
+
+# 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
+    yes:0)
+	at_msg="UNEXPECTED PASS"
+	at_res=xpass
+	at_errexit=$at_errexit_p
+	at_color=$at_red
+	;;
+    no:0)
+	at_msg="ok"
+	at_res=pass
+	at_errexit=false
+	at_color=$at_grn
+	;;
+    *:77)
+	at_msg='skipped ('`cat "$at_check_line_file"`')'
+	at_res=skip
+	at_errexit=false
+	at_color=$at_blu
+	;;
+    no:* | *:99)
+	at_msg='FAILED ('`cat "$at_check_line_file"`')'
+	at_res=fail
+	at_errexit=$at_errexit_p
+	at_color=$at_red
+	;;
+    yes:*)
+	at_msg='expected failure ('`cat "$at_check_line_file"`')'
+	at_res=xfail
+	at_errexit=false
+	at_color=$at_lgn
+	;;
+  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_color$at_msg$at_std"
+  else
+    # Make sure there is a separator even with long titles.
+    $as_echo " $at_color$at_msg$at_std"
+  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
+      # or the success was unexpected.
+      if $at_debug_p || test $at_res = xpass; then
+	at_fn_create_debugging_script
+	if test $at_res = xpass && $at_errexit; then
+	  echo stop > "$at_stop_file"
+	fi
+      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" | sed -n 1,${at_jobs}p`
+
+  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
+      if $at_first; then
+	exec 7>"$at_job_fifo"
+      else
+	exec 6<&-
+      fi
+      trap 'set +x; set +e
+	    trap "" PIPE
+	    echo stop > "$at_stop_file"
+	    echo >&7
+	    as_fn_exit 141' PIPE
+      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
+      echo >&7
+    ) &
+    $at_job_control_off
+    if $at_first; then
+      at_first=false
+      exec 6<"$at_job_fifo" 7>"$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
+  exec 7>&-
+  # 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
+$as_echo "## ------------- ##
+## Test results. ##
+## ------------- ##"
+echo
+{
+  echo
+  $as_echo "## ------------- ##
+## Test results. ##
+## ------------- ##"
+  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."
+  at_color=$at_red
+else
+  # Don't you just love exponential explosion of the number of cases?
+  at_color=$at_red
+  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." at_color=$at_grn ;;
+    0:0:*) at_result="$at_result behaved as expected." at_color=$at_lgn ;;
+
+    # 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_color$at_result$at_std"
+  echo "$at_result" >&5
+else
+  echo "${at_color}ERROR: $at_result$at_std" >&2
+  echo "ERROR: $at_result" >&5
+  {
+    echo
+    $as_echo "## ------------------------ ##
+## Summary of the failures. ##
+## ------------------------ ##"
+
+    # 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
+      $as_echo "## ---------------------- ##
+## Detailed failed tests. ##
+## ---------------------- ##"
+      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.14.0] $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
+at_fn_group_banner 1 'getdapTest.at:34' \
+  "getdap -d http://test.opendap.org/dap/data/nc/fnoc1.nc getdap-testsuite/fnoc1.nc.dds (pass)" ""
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+(
+  $as_echo "1. $at_setup_line: testing $at_desc ..."
+  $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/getdapTest.at:34: \$abs_builddir/../getdap -d http://test.opendap.org/dap/data/nc/fnoc1.nc || true"
+at_fn_check_prepare_dynamic "$abs_builddir/../getdap -d http://test.opendap.org/dap/data/nc/fnoc1.nc || true" "getdapTest.at:34"
+( $at_check_trace; $abs_builddir/../getdap -d http://test.opendap.org/dap/data/nc/fnoc1.nc || true
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/getdapTest.at:34"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/getdapTest.at:34: diff -b -B \$abs_srcdir/getdap-testsuite/fnoc1.nc.dds stdout || diff -b -B \$abs_srcdir/getdap-testsuite/fnoc1.nc.dds stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/getdap-testsuite/fnoc1.nc.dds stdout || diff -b -B $abs_srcdir/getdap-testsuite/fnoc1.nc.dds stderr" "getdapTest.at:34"
+( $at_check_trace; diff -b -B $abs_srcdir/getdap-testsuite/fnoc1.nc.dds stdout || diff -b -B $abs_srcdir/getdap-testsuite/fnoc1.nc.dds stderr
+) >>"$at_stdout" 2>>"$at_stderr" 5>&-
+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/getdapTest.at:34"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 7>&- | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_1
diff --git a/tests/getdapTest.at b/tests/getdapTest.at
new file mode 100644
index 0000000..3f27cfe
--- /dev/null
+++ b/tests/getdapTest.at
@@ -0,0 +1,34 @@
+# Process with autom4te to create an -*- Autotest -*- test suite.
+
+AT_INIT([getdap])
+
+# AT_ARG_OPTION_ARG([generate],
+#    [--generate=arg   Build the baseline file for test 'arg'],
+#    dnl Break the arg into the last thing (file | url) and all of the previous things (switches)
+#    [url=
+#    
+#    echo "getdap $at_arg_generate > $at_arg_generate_parse.baseline 2>&1";
+#     ./dmr-test -x -p $at_arg_generate_parse > $at_arg_generate_parse.baseline 2>&1;
+#     echo "Built baseline for $at_arg_generate_parse";
+#     exit],[])
+
+# Usage: GETDAP_TEST(<flags>, <path|url>, <baseline file>, <xfail?>)
+
+m4_define([GETDAP_TEST], [
+    AT_SETUP([getdap $1 $2 $3 ($4)])
+    AT_KEYWORDS([getdap])
+
+    # 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/../getdap $1 $2 || true], [], [stdout], [stderr])
+    AT_CHECK([diff -b -B $abs_srcdir/$3 stdout || diff -b -B $abs_srcdir/$3 stderr], [], [ignore],[],[])
+    AT_XFAIL_IF([test "$4" = "xfail"])
+    AT_CLEANUP
+])
+
+GETDAP_TEST([-d], [http://test.opendap.org/dap/data/nc/fnoc1.nc], [getdap-testsuite/fnoc1.nc.dds], [pass])
diff --git a/tests/package.m4 b/tests/package.m4
index 162600e..ae0356e 100644
--- a/tests/package.m4
+++ b/tests/package.m4
@@ -1,6 +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.12.0])
-m4_define([AT_PACKAGE_STRING],    [libdap 3.12.0])
+m4_define([AT_PACKAGE_VERSION],   [3.14.0])
+m4_define([AT_PACKAGE_STRING],    [libdap 3.14.0])
 m4_define([AT_PACKAGE_BUGREPORT], [opendap-tech at opendap.org])
diff --git a/unit-tests/AttrTableTest.cc b/unit-tests/AttrTableTest.cc
index 2f16a88..1bb3cf7 100644
--- a/unit-tests/AttrTableTest.cc
+++ b/unit-tests/AttrTableTest.cc
@@ -41,6 +41,12 @@
 #include "debug.h"
 
 #include "testFile.h"
+#include "GetOpt.h"
+
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
 
 using namespace CppUnit;
 using namespace std;
@@ -302,10 +308,6 @@ String longer%20name \"second test\";";
                 CPPUNIT_ASSERT("Caught Error exception!" && false);
             }
             try {
-#if 0
-                string sof;
-                FILE2string(sof, of, top->print(of, ""));
-#endif
                 ostringstream oss;
                 top->print(oss);
                 Regex r(".*Data%20Field \\{\n\
@@ -345,36 +347,46 @@ String longer%20name \"second test\";";
             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'.
+            // container named 'a'.
+            AttrTable *at2;
             try {
-                AttrTable *at2 = new AttrTable;
+                at2 = new AttrTable;
+                at2->set_name("at2");
                 at2->append_attr("color", "String", "red");
-                AttrTable *cont_at2 = at2->append_container("a");
+                AttrTable *cont_at2 = at2->append_container("cont_at2");
                 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");
+                i++ ;
+                CPPUNIT_ASSERT(at2->get_name(i) == "cont_at2");
+
                 at2->del_attr_table(i);
+
                 i = at2->attr_begin();
                 CPPUNIT_ASSERT(at2->get_name(i) == "color");
-		i++ ;
+                i++ ;
                 CPPUNIT_ASSERT(i == at2->attr_end());
+
+                delete at2; at2 = 0;
             }
             catch (Error &e) {
                 cerr << "Error: " << e.get_error_message() << endl;
+                delete at2; at2 = 0;
                 throw;
             }
             catch (...) {
                 cerr << "caught an exception!" << endl;
+                delete at2; at2 = 0;
                 throw;
             }
         }
@@ -401,13 +413,39 @@ String longer%20name \"second test\";";
 
 } // namespace libdap
 
-int main(int, char**)
+int
+main(int argc, char *argv[])
 {
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+            case 'd':
+                debug = 1;  // debug is a static global
+                break;
+            default:
+                break;
+        }
+
     CppUnit::TextTestRunner runner;
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
 
-    bool wasSuccessful = runner.run("", false);
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::AttrTableTest::") + argv[i++];
+            if (debug)
+                cerr << "Running " << test << endl;
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
 
     return wasSuccessful ? 0 : 1;
 }
-
diff --git a/unit-tests/D4-marshaller/test_cmp.dat b/unit-tests/D4-marshaller/test_cmp.dat
new file mode 100644
index 0000000..b66efb8
Binary files /dev/null and b/unit-tests/D4-marshaller/test_cmp.dat differ
diff --git a/unit-tests/D4-marshaller/test_opaque_1_bin.dat b/unit-tests/D4-marshaller/test_opaque_1_bin.dat
new file mode 100644
index 0000000..5e52c65
Binary files /dev/null and b/unit-tests/D4-marshaller/test_opaque_1_bin.dat differ
diff --git a/unit-tests/D4-marshaller/test_opaque_1_bin.dat.sav b/unit-tests/D4-marshaller/test_opaque_1_bin.dat.sav
new file mode 100644
index 0000000..4cc6ef3
Binary files /dev/null and b/unit-tests/D4-marshaller/test_opaque_1_bin.dat.sav differ
diff --git a/unit-tests/D4-marshaller/test_scalars_1.dat b/unit-tests/D4-marshaller/test_scalars_1.dat
new file mode 100644
index 0000000..c212499
Binary files /dev/null and b/unit-tests/D4-marshaller/test_scalars_1.dat differ
diff --git a/unit-tests/D4-marshaller/test_scalars_1_bin.dat b/unit-tests/D4-marshaller/test_scalars_1_bin.dat
new file mode 100644
index 0000000..6515746
Binary files /dev/null and b/unit-tests/D4-marshaller/test_scalars_1_bin.dat differ
diff --git a/unit-tests/D4-marshaller/test_scalars_2.dat b/unit-tests/D4-marshaller/test_scalars_2.dat
new file mode 100644
index 0000000..5d7d0ff
Binary files /dev/null and b/unit-tests/D4-marshaller/test_scalars_2.dat differ
diff --git a/unit-tests/D4-marshaller/test_scalars_2_bin.dat b/unit-tests/D4-marshaller/test_scalars_2_bin.dat
new file mode 100644
index 0000000..fdf84e9
Binary files /dev/null and b/unit-tests/D4-marshaller/test_scalars_2_bin.dat differ
diff --git a/unit-tests/D4-marshaller/test_scalars_3_bin.dat b/unit-tests/D4-marshaller/test_scalars_3_bin.dat
new file mode 100644
index 0000000..0098c35
Binary files /dev/null and b/unit-tests/D4-marshaller/test_scalars_3_bin.dat differ
diff --git a/unit-tests/D4-marshaller/test_vector_1_bin.dat b/unit-tests/D4-marshaller/test_vector_1_bin.dat
new file mode 100644
index 0000000..bfcb051
Binary files /dev/null and b/unit-tests/D4-marshaller/test_vector_1_bin.dat differ
diff --git a/unit-tests/D4-marshaller/test_vector_2_bin.dat b/unit-tests/D4-marshaller/test_vector_2_bin.dat
new file mode 100644
index 0000000..59791e3
Binary files /dev/null and b/unit-tests/D4-marshaller/test_vector_2_bin.dat differ
diff --git a/unit-tests/D4-xml/D4AsyncAccepted.xml b/unit-tests/D4-xml/D4AsyncAccepted.xml
new file mode 100644
index 0000000..740b83b
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncAccepted.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<dap:AsynchronousResponse status="accepted" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+    <dap:expectedDelay seconds="6003"/>
+    <dap:responseLifetime seconds="600009"/>
+    <dap:link href="http://test.opendap.org:8080/opendap/storedResults/result_87697163.dap"/>
+</dap:AsynchronousResponse>
diff --git a/unit-tests/D4-xml/D4AsyncAccepted_StyleRef.xml b/unit-tests/D4-xml/D4AsyncAccepted_StyleRef.xml
new file mode 100644
index 0000000..08ebfb2
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncAccepted_StyleRef.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml-stylesheet type='text/xsl' href='http://someServer:8080/opendap/xsl/asyncResponse.xsl'?>
+<dap:AsynchronousResponse status="accepted" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+    <dap:expectedDelay seconds="6003"/>
+    <dap:responseLifetime seconds="600009"/>
+    <dap:link href="http://test.opendap.org:8080/opendap/storedResults/result_87697163.dap"/>
+</dap:AsynchronousResponse>
diff --git a/unit-tests/D4-xml/D4AsyncGone.xml b/unit-tests/D4-xml/D4AsyncGone.xml
new file mode 100644
index 0000000..0cbd7b3
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncGone.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<dap:AsynchronousResponse status="gone" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#"/>
diff --git a/unit-tests/D4-xml/D4AsyncGone_StyleRef.xml b/unit-tests/D4-xml/D4AsyncGone_StyleRef.xml
new file mode 100644
index 0000000..8917cea
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncGone_StyleRef.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml-stylesheet type='text/xsl' href='http://someServer:8080/opendap/xsl/asyncResponse.xsl'?>
+<dap:AsynchronousResponse status="gone" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#"/>
diff --git a/unit-tests/D4-xml/D4AsyncPending.xml b/unit-tests/D4-xml/D4AsyncPending.xml
new file mode 100644
index 0000000..7012099
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncPending.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<dap:AsynchronousResponse status="pending" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#"/>
diff --git a/unit-tests/D4-xml/D4AsyncPending_StyleRef.xml b/unit-tests/D4-xml/D4AsyncPending_StyleRef.xml
new file mode 100644
index 0000000..2a8a2de
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncPending_StyleRef.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml-stylesheet type='text/xsl' href='http://someServer:8080/opendap/xsl/asyncResponse.xsl'?>
+<dap:AsynchronousResponse status="pending" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#"/>
diff --git a/unit-tests/D4-xml/D4AsyncRejected.xml b/unit-tests/D4-xml/D4AsyncRejected.xml
new file mode 100644
index 0000000..13b8157
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncRejected.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<dap:AsynchronousResponse status="rejected" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+    <dap:reason code="time"/>
+    <dap:description>The time to process your request is longer than the time you indicated was acceptable.</dap:description>
+</dap:AsynchronousResponse>
diff --git a/unit-tests/D4-xml/D4AsyncRejected_StyleRef.xml b/unit-tests/D4-xml/D4AsyncRejected_StyleRef.xml
new file mode 100644
index 0000000..d5d17b5
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncRejected_StyleRef.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml-stylesheet type='text/xsl' href='http://someServer:8080/opendap/xsl/asyncResponse.xsl'?>
+<dap:AsynchronousResponse status="rejected" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+    <dap:reason code="time"/>
+    <dap:description>The time to process your request is longer than the time you indicated was acceptable.</dap:description>
+</dap:AsynchronousResponse>
diff --git a/unit-tests/D4-xml/D4AsyncRequired.xml b/unit-tests/D4-xml/D4AsyncRequired.xml
new file mode 100644
index 0000000..14cbe90
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncRequired.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<dap:AsynchronousResponse status="required" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+    <dap:expectedDelay seconds="6001"/>
+    <dap:responseLifetime seconds="600007"/>
+</dap:AsynchronousResponse>
diff --git a/unit-tests/D4-xml/D4AsyncRequired_StyleRef.xml b/unit-tests/D4-xml/D4AsyncRequired_StyleRef.xml
new file mode 100644
index 0000000..1037e98
--- /dev/null
+++ b/unit-tests/D4-xml/D4AsyncRequired_StyleRef.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml-stylesheet type='text/xsl' href='http://someServer:8080/opendap/xsl/asyncResponse.xsl'?>
+<dap:AsynchronousResponse status="required" xmlns:dap="http://xml.opendap.org/ns/DAP/4.0#">
+    <dap:expectedDelay seconds="6001"/>
+    <dap:responseLifetime seconds="600007"/>
+</dap:AsynchronousResponse>
diff --git a/unit-tests/D4-xml/D4Attributes_1.xml b/unit-tests/D4-xml/D4Attributes_1.xml
new file mode 100644
index 0000000..02b5da8
--- /dev/null
+++ b/unit-tests/D4-xml/D4Attributes_1.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Attribute name="first" type="Byte">
+    <Value>1</Value>
+    <Value>2</Value>
+</Attribute>
diff --git a/unit-tests/D4-xml/D4Attributes_2.xml b/unit-tests/D4-xml/D4Attributes_2.xml
new file mode 100644
index 0000000..36c6eef
--- /dev/null
+++ b/unit-tests/D4-xml/D4Attributes_2.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Attribute name="first" type="Byte">
+    <Value>1</Value>
+    <Value>2</Value>
+</Attribute>
+<Attribute name="second" type="Int32">
+    <Value>10000</Value>
+</Attribute>
diff --git a/unit-tests/D4-xml/D4Attributes_3.xml b/unit-tests/D4-xml/D4Attributes_3.xml
new file mode 100644
index 0000000..e6d9238
--- /dev/null
+++ b/unit-tests/D4-xml/D4Attributes_3.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Attribute name="first" type="Byte">
+    <Value>1</Value>
+    <Value>2</Value>
+</Attribute>
+<Attribute name="second" type="Int32">
+    <Value>10000</Value>
+</Attribute>
+<Attribute name="container_1" type="Container">
+    <Attribute name="color" type="String">
+        <Value>red</Value>
+        <Value>blue</Value>
+        <Value>green</Value>
+    </Attribute>
+</Attribute>
+<Attribute name="container_2" type="Container">
+    <Attribute name="control" type="Int32">
+        <Value>10000</Value>
+    </Attribute>
+    <Attribute name="container_1" type="Container">
+        <Attribute name="color" type="String">
+            <Value>red</Value>
+            <Value>blue</Value>
+            <Value>green</Value>
+        </Attribute>
+    </Attribute>
+</Attribute>
diff --git a/unit-tests/D4-xml/D4Attributes_assignment.xml b/unit-tests/D4-xml/D4Attributes_assignment.xml
new file mode 100644
index 0000000..36c6eef
--- /dev/null
+++ b/unit-tests/D4-xml/D4Attributes_assignment.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Attribute name="first" type="Byte">
+    <Value>1</Value>
+    <Value>2</Value>
+</Attribute>
+<Attribute name="second" type="Int32">
+    <Value>10000</Value>
+</Attribute>
diff --git a/unit-tests/D4-xml/D4Attributes_assignment_2.xml b/unit-tests/D4-xml/D4Attributes_assignment_2.xml
new file mode 100644
index 0000000..e6d9238
--- /dev/null
+++ b/unit-tests/D4-xml/D4Attributes_assignment_2.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Attribute name="first" type="Byte">
+    <Value>1</Value>
+    <Value>2</Value>
+</Attribute>
+<Attribute name="second" type="Int32">
+    <Value>10000</Value>
+</Attribute>
+<Attribute name="container_1" type="Container">
+    <Attribute name="color" type="String">
+        <Value>red</Value>
+        <Value>blue</Value>
+        <Value>green</Value>
+    </Attribute>
+</Attribute>
+<Attribute name="container_2" type="Container">
+    <Attribute name="control" type="Int32">
+        <Value>10000</Value>
+    </Attribute>
+    <Attribute name="container_1" type="Container">
+        <Attribute name="color" type="String">
+            <Value>red</Value>
+            <Value>blue</Value>
+            <Value>green</Value>
+        </Attribute>
+    </Attribute>
+</Attribute>
diff --git a/unit-tests/D4-xml/D4Attributes_copy_ctor.xml b/unit-tests/D4-xml/D4Attributes_copy_ctor.xml
new file mode 100644
index 0000000..36c6eef
--- /dev/null
+++ b/unit-tests/D4-xml/D4Attributes_copy_ctor.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Attribute name="first" type="Byte">
+    <Value>1</Value>
+    <Value>2</Value>
+</Attribute>
+<Attribute name="second" type="Int32">
+    <Value>10000</Value>
+</Attribute>
diff --git a/unit-tests/D4-xml/D4Attributes_empty.xml b/unit-tests/D4-xml/D4Attributes_empty.xml
new file mode 100644
index 0000000..89a325e
--- /dev/null
+++ b/unit-tests/D4-xml/D4Attributes_empty.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
diff --git a/unit-tests/D4-xml/D4Attributes_values_1.xml b/unit-tests/D4-xml/D4Attributes_values_1.xml
new file mode 100644
index 0000000..02b5da8
--- /dev/null
+++ b/unit-tests/D4-xml/D4Attributes_values_1.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Attribute name="first" type="Byte">
+    <Value>1</Value>
+    <Value>2</Value>
+</Attribute>
diff --git a/unit-tests/D4-xml/D4Dimensions_3.xml b/unit-tests/D4-xml/D4Dimensions_3.xml
index f19426f..bb86d67 100644
--- a/unit-tests/D4-xml/D4Dimensions_3.xml
+++ b/unit-tests/D4-xml/D4Dimensions_3.xml
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <Dimension name="first" size="10"/>
 <Dimension name="second" size="100"/>
-<Dimension name="third" unlimited="true"/>
+<Dimension name="third" size="1000"/>
diff --git a/unit-tests/D4-xml/D4Dimensions_4.xml b/unit-tests/D4-xml/D4Dimensions_4.xml
index f9e0362..0e7042f 100644
--- a/unit-tests/D4-xml/D4Dimensions_4.xml
+++ b/unit-tests/D4-xml/D4Dimensions_4.xml
@@ -2,4 +2,4 @@
 <Dimension name="first" size="10"/>
 <Dimension name="odd" size="20"/>
 <Dimension name="second" size="100"/>
-<Dimension name="third" unlimited="true"/>
+<Dimension name="third" size="1000"/>
diff --git a/unit-tests/D4-xml/D4Enum_1.xml b/unit-tests/D4-xml/D4Enum_1.xml
new file mode 100644
index 0000000..dc5227c
--- /dev/null
+++ b/unit-tests/D4-xml/D4Enum_1.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Enum name="test" enum="Colors"/>
diff --git a/unit-tests/D4-xml/D4Enum_2.txt b/unit-tests/D4-xml/D4Enum_2.txt
new file mode 100644
index 0000000..802bf3c
--- /dev/null
+++ b/unit-tests/D4-xml/D4Enum_2.txt
@@ -0,0 +1 @@
+Enum test = 200;
diff --git a/unit-tests/D4-xml/D4Group_empty.xml b/unit-tests/D4-xml/D4Group_empty.xml
new file mode 100644
index 0000000..89a325e
--- /dev/null
+++ b/unit-tests/D4-xml/D4Group_empty.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
diff --git a/unit-tests/D4-xml/D4Group_everything.xml b/unit-tests/D4-xml/D4Group_everything.xml
new file mode 100644
index 0000000..4db6c07
--- /dev/null
+++ b/unit-tests/D4-xml/D4Group_everything.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dimension name="lat" size="1024"/>
+<Dimension name="lon" size="1024"/>
+<Dimension name="time" size="20"/>
+<Enumeration name="colors" basetype="Byte">
+    <EnumConst name="red" value="1"/>
+    <EnumConst name="green" value="2"/>
+    <EnumConst name="blue" value="3"/>
+</Enumeration>
+<Byte name="b"/>
+<Int64 name="i64"/>
+<Attribute name="test" type="Int16">
+    <Value>1</Value>
+</Attribute>
+<Group name="child">
+    <Dimension name="lat" size="1024"/>
+    <Dimension name="lon" size="1024"/>
+    <Dimension name="time" size="20"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b"/>
+    <Int64 name="i64"/>
+    <Attribute name="test" type="Int16">
+        <Value>1</Value>
+    </Attribute>
+</Group>
diff --git a/unit-tests/D4-xml/D4Group_named_empty.xml b/unit-tests/D4-xml/D4Group_named_empty.xml
new file mode 100644
index 0000000..4dcf1e3
--- /dev/null
+++ b/unit-tests/D4-xml/D4Group_named_empty.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Group name="test"/>
diff --git a/unit-tests/D4-xml/D4Group_named_with_scalars.xml b/unit-tests/D4-xml/D4Group_named_with_scalars.xml
new file mode 100644
index 0000000..552f372
--- /dev/null
+++ b/unit-tests/D4-xml/D4Group_named_with_scalars.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Group name="test">
+    <Byte name="b"/>
+    <Int64 name="i64"/>
+</Group>
diff --git a/unit-tests/D4-xml/D4Group_named_with_scalars_and_stuff.xml b/unit-tests/D4-xml/D4Group_named_with_scalars_and_stuff.xml
new file mode 100644
index 0000000..3e1ee95
--- /dev/null
+++ b/unit-tests/D4-xml/D4Group_named_with_scalars_and_stuff.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Group name="test">
+    <Dimension name="lat" size="1024"/>
+    <Dimension name="lon" size="1024"/>
+    <Dimension name="time" size="20"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b"/>
+    <Int64 name="i64"/>
+    <Attribute name="test" type="Int16">
+        <Value>1</Value>
+    </Attribute>
+</Group>
diff --git a/unit-tests/D4-xml/D4Group_with_scalars.xml b/unit-tests/D4-xml/D4Group_with_scalars.xml
new file mode 100644
index 0000000..2c3f5dd
--- /dev/null
+++ b/unit-tests/D4-xml/D4Group_with_scalars.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Byte name="b"/>
+<Int64 name="i64"/>
diff --git a/unit-tests/D4-xml/D4Group_with_scalars_and_stuff.xml b/unit-tests/D4-xml/D4Group_with_scalars_and_stuff.xml
new file mode 100644
index 0000000..edffb37
--- /dev/null
+++ b/unit-tests/D4-xml/D4Group_with_scalars_and_stuff.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dimension name="lat" size="1024"/>
+<Dimension name="lon" size="1024"/>
+<Dimension name="time" size="20"/>
+<Enumeration name="colors" basetype="Byte">
+    <EnumConst name="red" value="1"/>
+    <EnumConst name="green" value="2"/>
+    <EnumConst name="blue" value="3"/>
+</Enumeration>
+<Byte name="b"/>
+<Int64 name="i64"/>
+<Attribute name="test" type="Int16">
+    <Value>1</Value>
+</Attribute>
diff --git a/unit-tests/D4-xml/DMR_0.1.xml b/unit-tests/D4-xml/DMR_0.1.xml
new file mode 100644
index 0000000..505c1b2
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_0.1.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_0.xml"    
+    name="DMR_0"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Attribute name="test" type="Int16">
+        <Value>1</Value>
+        <Value>2</Value>
+        <Value>3</Value>
+    </Attribute>
+    <Attribute name="DAP4_switches" type="Container">
+        <Attribute name="public_key" type="String">
+            <Value>some_large_hex_value</Value>
+        </Attribute>
+        <Attribute name="colors" type="String">
+            <Value>red</Value>
+            <Value>green</Value>
+            <Value>blue</Value>
+        </Attribute>
+        <Attribute name="temp" type="Float32">
+            <Value>98.6</Value>
+        </Attribute>
+        <Attribute type="OtherXML" name="xmltest">
+            <xml>barf</xml>
+        </Attribute>
+    </Attribute>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_0.1_baseline.xml b/unit-tests/D4-xml/DMR_0.1_baseline.xml
new file mode 100644
index 0000000..9dae03f
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_0.1_baseline.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_0.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_0">
+    <Attribute name="test" type="Int16">
+        <Value>1</Value>
+        <Value>2</Value>
+        <Value>3</Value>
+    </Attribute>
+    <Attribute name="DAP4_switches" type="Container">
+        <Attribute name="public_key" type="String">
+            <Value>some_large_hex_value</Value>
+        </Attribute>
+        <Attribute name="colors" type="String">
+            <Value>red</Value>
+            <Value>green</Value>
+            <Value>blue</Value>
+        </Attribute>
+        <Attribute name="temp" type="Float32">
+            <Value>98.6</Value>
+        </Attribute>
+        <Attribute name="xmltest" type="OtherXML">            <xml>barf</xml>        </Attribute>
+    </Attribute>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_0.xml b/unit-tests/D4-xml/DMR_0.xml
new file mode 100644
index 0000000..23486b2
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_0.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_0.xml"    
+    name="DMR_0"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Attribute name="test" type="Int16">
+        <Value>1</Value>
+        <Value>2</Value>
+        <Value>3</Value>
+    </Attribute>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_0_baseline.xml b/unit-tests/D4-xml/DMR_0_baseline.xml
new file mode 100644
index 0000000..4efe50d
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_0_baseline.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_0.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_0">
+    <Attribute name="test" type="Int16">
+        <Value>1</Value>
+        <Value>2</Value>
+        <Value>3</Value>
+    </Attribute>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_1.xml b/unit-tests/D4-xml/DMR_1.xml
new file mode 100644
index 0000000..e1cb87d
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_1.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_1.xml"    
+    name="DMR_1"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_1_baseline.xml b/unit-tests/D4-xml/DMR_1_baseline.xml
new file mode 100644
index 0000000..6273423
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_1_baseline.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_1.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_1">
+    <Dimension name="dim1" size="5"/>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_2.1.xml b/unit-tests/D4-xml/DMR_2.1.xml
new file mode 100644
index 0000000..1d69495
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_2.1.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_2.1.xml"    
+    name="DMR_2.1"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    
+    <Enum name="e1" enum="colors"/>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_2.1_baseline.xml b/unit-tests/D4-xml/DMR_2.1_baseline.xml
new file mode 100644
index 0000000..1b6fa84
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_2.1_baseline.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_2.1.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_2.1">
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Enum name="e1" enum="/colors"/>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_2.xml b/unit-tests/D4-xml/DMR_2.xml
new file mode 100644
index 0000000..beb1990
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_2.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_2.xml"    
+    name="DMR_2"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_2_baseline.xml b/unit-tests/D4-xml/DMR_2_baseline.xml
new file mode 100644
index 0000000..fea8587
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_2_baseline.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_2.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_2">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_3.1.xml b/unit-tests/D4-xml/DMR_3.1.xml
new file mode 100644
index 0000000..1764a63
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.1.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_3.xml"    
+    name="DMR_3"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1">
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+        <Attribute name="DAP4_switches" type="Container">
+            <Attribute name="public_key" type="String">
+                <Value>some_large_hex_value</Value>
+            </Attribute>
+            <Attribute name="colors" type="String">
+                <Value>red</Value>
+                <Value>green</Value>
+                <Value>blue</Value>
+            </Attribute>
+            <Attribute name="temp" type="Float32">
+                <Value>98.6</Value>
+            </Attribute>
+            <Attribute type="OtherXML" name="xmltest">
+                <xml>barf</xml>
+            </Attribute>
+        </Attribute>
+    </Byte>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_3.1_baseline.xml b/unit-tests/D4-xml/DMR_3.1_baseline.xml
new file mode 100644
index 0000000..fa86eb8
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.1_baseline.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_3.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_3">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1">
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+        <Attribute name="DAP4_switches" type="Container">
+            <Attribute name="public_key" type="String">
+                <Value>some_large_hex_value</Value>
+            </Attribute>
+            <Attribute name="colors" type="String">
+                <Value>red</Value>
+                <Value>green</Value>
+                <Value>blue</Value>
+            </Attribute>
+            <Attribute name="temp" type="Float32">
+                <Value>98.6</Value>
+            </Attribute>
+            <Attribute name="xmltest" type="OtherXML">                <xml>barf</xml>            </Attribute>
+        </Attribute>
+    </Byte>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_3.2.xml b/unit-tests/D4-xml/DMR_3.2.xml
new file mode 100644
index 0000000..ac7611d
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.2.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_3.xml"    
+    name="DMR_3"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Byte name="b1">
+        <Dim size="10"/>
+    </Byte>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_3.2_baseline.xml b/unit-tests/D4-xml/DMR_3.2_baseline.xml
new file mode 100644
index 0000000..8a89598
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.2_baseline.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_3.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_3">
+    <Byte name="b1">
+        <Dim size="10"/>
+    </Byte>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_3.3.xml b/unit-tests/D4-xml/DMR_3.3.xml
new file mode 100644
index 0000000..86a8347
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.3.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_3.xml"    
+    name="DMR_3"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1">
+        <Dim size="20"/>
+        <Dim size="30"/>
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+        <Attribute name="DAP4_switches" type="Container">
+            <Attribute name="public_key" type="String">
+                <Value>some_large_hex_value</Value>
+            </Attribute>
+            <Attribute name="colors" type="String">
+                <Value>red</Value>
+                <Value>green</Value>
+                <Value>blue</Value>
+            </Attribute>
+            <Attribute name="temp" type="Float32">
+                <Value>98.6</Value>
+            </Attribute>
+            <Attribute type="OtherXML" name="xmltest">
+                <xml>barf</xml>
+            </Attribute>
+        </Attribute>
+    </Byte>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_3.3_baseline.xml b/unit-tests/D4-xml/DMR_3.3_baseline.xml
new file mode 100644
index 0000000..3dab03f
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.3_baseline.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_3.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_3">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1">
+        <Dim size="20"/>
+        <Dim size="30"/>
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+        <Attribute name="DAP4_switches" type="Container">
+            <Attribute name="public_key" type="String">
+                <Value>some_large_hex_value</Value>
+            </Attribute>
+            <Attribute name="colors" type="String">
+                <Value>red</Value>
+                <Value>green</Value>
+                <Value>blue</Value>
+            </Attribute>
+            <Attribute name="temp" type="Float32">
+                <Value>98.6</Value>
+            </Attribute>
+            <Attribute name="xmltest" type="OtherXML">                <xml>barf</xml>            </Attribute>
+        </Attribute>
+    </Byte>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_3.4.xml b/unit-tests/D4-xml/DMR_3.4.xml
new file mode 100644
index 0000000..f3e481d
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.4.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_3.xml"    
+    name="DMR_3"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1">
+        <Dim name="dim1"/>
+        <Dim size="30"/>
+    </Byte>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_3.4_baseline.xml b/unit-tests/D4-xml/DMR_3.4_baseline.xml
new file mode 100644
index 0000000..f3dbff2
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.4_baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_3.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_3">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1">
+        <Dim name="/dim1"/>
+        <Dim size="30"/>
+    </Byte>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_3.5.xml b/unit-tests/D4-xml/DMR_3.5.xml
new file mode 100644
index 0000000..22f5070
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.5.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_3.xml"    
+    name="DMR_3"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1">
+        <Dim name="dim1"/>
+        <Dim size="30"/>
+    </Byte>
+    <Group name="g1">
+        <Dimension name="dim1" size="10"/>
+        <Int32 name="thing1">
+            <Dim name="/dim1"/>
+            <Dim name="dim1"/>
+        </Int32>
+        <Int32 name="thing2">
+            <Dim name="/dim1"/>
+            <Dim name="/g1/dim1"/>
+        </Int32>
+        
+        <Group name="g2">
+            <Dimension name="dim1" size="20"/>
+            <Int32 name="thing1">
+                <Dim name="/dim1"/>
+                <Dim name="/g1/dim1"/>
+                <Dim name="dim1"/>
+            </Int32>
+        </Group> 
+        
+        <Int32 name="thing3">
+            <Dim name="/dim1"/>
+            <Dim name="dim1"/>
+            <Dim name="g2/dim1"/>
+        </Int32>
+        
+    </Group>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_3.5_baseline.xml b/unit-tests/D4-xml/DMR_3.5_baseline.xml
new file mode 100644
index 0000000..bad1c4f
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.5_baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_3.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_3">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1">
+        <Dim name="/dim1"/>
+        <Dim size="30"/>
+    </Byte>
+    <Group name="g1">
+        <Dimension name="dim1" size="10"/>
+        <Int32 name="thing1">
+            <Dim name="/dim1"/>
+            <Dim name="/g1/dim1"/>
+        </Int32>
+        <Int32 name="thing2">
+            <Dim name="/dim1"/>
+            <Dim name="/g1/dim1"/>
+        </Int32>
+        <Int32 name="thing3">
+            <Dim name="/dim1"/>
+            <Dim name="/g1/dim1"/>
+            <Dim name="/g1/g2/dim1"/>
+        </Int32>
+        <Group name="g2">
+            <Dimension name="dim1" size="20"/>
+            <Int32 name="thing1">
+                <Dim name="/dim1"/>
+                <Dim name="/g1/dim1"/>
+                <Dim name="/g1/g2/dim1"/>
+            </Int32>
+        </Group>
+    </Group>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_3.xml b/unit-tests/D4-xml/DMR_3.xml
new file mode 100644
index 0000000..507e117
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_3.xml"    
+    name="DMR_3"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_3_baseline.xml b/unit-tests/D4-xml/DMR_3_baseline.xml
new file mode 100644
index 0000000..5ccb2bc
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_3_baseline.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_3.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_3">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_4.1.xml b/unit-tests/D4-xml/DMR_4.1.xml
new file mode 100644
index 0000000..16037ad
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_4.1.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_4.1.xml"    
+    name="DMR_4.1"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="d1" size="5"/>
+    <Dimension name="d2" size="3"/>
+
+    <Opaque name="o">
+        <Dim name="d1"/>
+    </Opaque>
+
+    <Opaque name="p">
+        <Dim name="d1"/>
+        <Dim name="d2"/>
+    </Opaque>
+    
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_4.1_baseline.xml b/unit-tests/D4-xml/DMR_4.1_baseline.xml
new file mode 100644
index 0000000..a9c2fc3
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_4.1_baseline.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_4.1.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_4.1">
+    <Dimension name="d1" size="5"/>
+    <Dimension name="d2" size="3"/>
+    <Opaque name="o">
+        <Dim name="/d1"/>
+    </Opaque>
+    <Opaque name="p">
+        <Dim name="/d1"/>
+        <Dim name="/d2"/>
+    </Opaque>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_4.xml b/unit-tests/D4-xml/DMR_4.xml
new file mode 100644
index 0000000..a32a194
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_4.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_4.xml"    
+    name="DMR_4"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Char name  ="c1"/>
+    <Int8 name="i8"/>
+    <UInt8 name="ui8"/>
+    <Int16 name="i16"/>
+    <UInt16 name="ui16"/>
+    <Int32 name="i32"/>
+    <UInt32 name="ui32"/>
+    <Int64 name="i64"/>
+    <UInt64 name="ui64"/>
+    <Float32 name="f32"/>
+    <Float64 name="f64"/>
+    <String name="s"/>
+    <URL name="u"/>
+    <Enum name="e" enum="colors"/>
+    <Opaque name="o"/>
+
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_4_baseline.xml b/unit-tests/D4-xml/DMR_4_baseline.xml
new file mode 100644
index 0000000..241db52
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_4_baseline.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_4.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_4">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Char name="c1"/>
+    <Int8 name="i8"/>
+    <UInt8 name="ui8"/>
+    <Int16 name="i16"/>
+    <UInt16 name="ui16"/>
+    <Int32 name="i32"/>
+    <UInt32 name="ui32"/>
+    <Int64 name="i64"/>
+    <UInt64 name="ui64"/>
+    <Float32 name="f32"/>
+    <Float64 name="f64"/>
+    <String name="s"/>
+    <URL name="u"/>
+    <Enum name="e" enum="/colors"/>
+    <Opaque name="o"/>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_5.1.xml b/unit-tests/D4-xml/DMR_5.1.xml
new file mode 100644
index 0000000..6c39372
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_5.1.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_5.xml" name="DMR_5"
+    dapVersion="4.0" dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Structure name="s">
+        <Int8 name="i8"/>
+        <UInt8 name="ui8">
+            <Attribute name="test" type="Int16">
+                <Value>1</Value>
+                <Value>2</Value>
+                <Value>3</Value>
+            </Attribute>
+            <Attribute name="DAP4_switches" type="Container">
+                <Attribute name="public_key" type="String">
+                    <Value>some_large_hex_value</Value>
+                </Attribute>
+            </Attribute>
+        </UInt8>
+        <Int16 name="i16"/>
+        <UInt16 name="ui16"/>
+        <Int32 name="i32"/>
+        <UInt32 name="ui32"/>
+        <Int64 name="i64"/>
+        <UInt64 name="ui64"/>
+        <Float32 name="f32"/>
+        <Float64 name="f64"/>
+        <String name="s"/>
+        <URL name="u"/>
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+        <Attribute name="DAP4_switches" type="Container">
+            <Attribute name="public_key" type="String">
+                <Value>some_large_hex_value</Value>
+            </Attribute>
+            <Attribute name="colors" type="String">
+                <Value>red</Value>
+                <Value>green</Value>
+                <Value>blue</Value>
+            </Attribute>
+            <Attribute name="temp" type="Float32">
+                <Value>98.6</Value>
+            </Attribute>
+        </Attribute>
+    </Structure>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_5.1_baseline.xml b/unit-tests/D4-xml/DMR_5.1_baseline.xml
new file mode 100644
index 0000000..26e65f6
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_5.1_baseline.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_5.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_5">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Structure name="s">
+        <Int8 name="i8"/>
+        <UInt8 name="ui8">
+            <Attribute name="test" type="Int16">
+                <Value>1</Value>
+                <Value>2</Value>
+                <Value>3</Value>
+            </Attribute>
+            <Attribute name="DAP4_switches" type="Container">
+                <Attribute name="public_key" type="String">
+                    <Value>some_large_hex_value</Value>
+                </Attribute>
+            </Attribute>
+        </UInt8>
+        <Int16 name="i16"/>
+        <UInt16 name="ui16"/>
+        <Int32 name="i32"/>
+        <UInt32 name="ui32"/>
+        <Int64 name="i64"/>
+        <UInt64 name="ui64"/>
+        <Float32 name="f32"/>
+        <Float64 name="f64"/>
+        <String name="s"/>
+        <URL name="u"/>
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+        <Attribute name="DAP4_switches" type="Container">
+            <Attribute name="public_key" type="String">
+                <Value>some_large_hex_value</Value>
+            </Attribute>
+            <Attribute name="colors" type="String">
+                <Value>red</Value>
+                <Value>green</Value>
+                <Value>blue</Value>
+            </Attribute>
+            <Attribute name="temp" type="Float32">
+                <Value>98.6</Value>
+            </Attribute>
+        </Attribute>
+    </Structure>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_5.xml b/unit-tests/D4-xml/DMR_5.xml
new file mode 100644
index 0000000..56123a5
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_5.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_5.xml"    
+    name="DMR_5"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Structure name="s">
+        <Char name="c1"/>
+        <Int8 name="i8"/>
+        <UInt8 name="ui8"/>
+        <Int16 name="i16"/>
+        <UInt16 name="ui16"/>
+        <Int32 name="i32"/>
+        <UInt32 name="ui32"/>
+        <Int64 name="i64"/>
+        <UInt64 name="ui64"/>
+        <Float32 name="f32"/>
+        <Float64 name="f64"/>
+        <String name="s"/>
+        <URL name="u"/>
+        <Enum name="e" enum="colors"/>
+        <Opaque name="o"/>
+    </Structure>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_5_baseline.xml b/unit-tests/D4-xml/DMR_5_baseline.xml
new file mode 100644
index 0000000..000a42e
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_5_baseline.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_5.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_5">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Structure name="s">
+        <Char name="c1"/>
+        <Int8 name="i8"/>
+        <UInt8 name="ui8"/>
+        <Int16 name="i16"/>
+        <UInt16 name="ui16"/>
+        <Int32 name="i32"/>
+        <UInt32 name="ui32"/>
+        <Int64 name="i64"/>
+        <UInt64 name="ui64"/>
+        <Float32 name="f32"/>
+        <Float64 name="f64"/>
+        <String name="s"/>
+        <URL name="u"/>
+        <Enum name="e" enum="/colors"/>
+        <Opaque name="o"/>
+    </Structure>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_6.1.xml b/unit-tests/D4-xml/DMR_6.1.xml
new file mode 100644
index 0000000..be73019
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_6.1.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_6.xml"    
+    name="DMR_6"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Group name="g1">
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+        <Int8 name="i8"/>
+        <Structure name="s">
+            <Int16 name="i16"/>
+            <UInt16 name="ui16"/>
+            <URL name="u"/>
+        </Structure>        
+    </Group>
+    <Group name="g2">
+        <String name="s"/>
+        <Group name="gg2">
+            <Attribute name="test" type="Int16">
+                <Value>1</Value>
+                <Value>2</Value>
+                <Value>3</Value>
+            </Attribute>
+            <Float64 name="f64"/>
+            <Structure name="s">
+                <Int32 name="i16"/>
+                <UInt32 name="ui16"/>
+                <URL name="u"/>
+            </Structure>
+        </Group>
+    </Group>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_6.1_baseline.xml b/unit-tests/D4-xml/DMR_6.1_baseline.xml
new file mode 100644
index 0000000..267b76a
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_6.1_baseline.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_6.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_6">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Group name="g1">
+        <Int8 name="i8"/>
+        <Structure name="s">
+            <Int16 name="i16"/>
+            <UInt16 name="ui16"/>
+            <URL name="u"/>
+        </Structure>
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+    </Group>
+    <Group name="g2">
+        <String name="s"/>
+        <Group name="gg2">
+            <Float64 name="f64"/>
+            <Structure name="s">
+                <Int32 name="i16"/>
+                <UInt32 name="ui16"/>
+                <URL name="u"/>
+            </Structure>
+            <Attribute name="test" type="Int16">
+                <Value>1</Value>
+                <Value>2</Value>
+                <Value>3</Value>
+            </Attribute>
+        </Group>
+    </Group>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_6.2.xml b/unit-tests/D4-xml/DMR_6.2.xml
new file mode 100644
index 0000000..dbccdd7
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_6.2.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_6.2.xml"    
+    name="DMR_6.2"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    
+    <Enum name="e" enum="colors"/>
+    
+    <Byte name="b1"/>
+    <Group name="g1">
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+        
+        <Enum name="e" enum="/colors"/>
+        
+    </Group>
+     <Group name="g2">
+        <Enumeration name="shades" basetype="UInt16">
+            <EnumConst name="white" value="1"/>
+            <EnumConst name="light" value="2"/>
+            <EnumConst name="med" value="3"/>
+            <EnumConst name="dark" value="4"/>
+            <EnumConst name="black" value="5"/>
+        </Enumeration>
+    
+        <Enum name="e" enum="shades"/>
+        
+        <Group name="gg2">
+            <Attribute name="test" type="Int16">
+                <Value>1</Value>
+                <Value>2</Value>
+                <Value>3</Value>
+            </Attribute>
+
+            <Enum name="e" enum="/g2/shades"/>
+
+        </Group>
+    </Group>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_6.2_baseline.xml b/unit-tests/D4-xml/DMR_6.2_baseline.xml
new file mode 100644
index 0000000..4b9d365
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_6.2_baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_6.2.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_6.2">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Enum name="e" enum="/colors"/>
+    <Byte name="b1"/>
+    <Group name="g1">
+        <Enum name="e" enum="/colors"/>
+        <Attribute name="test" type="Int16">
+            <Value>1</Value>
+            <Value>2</Value>
+            <Value>3</Value>
+        </Attribute>
+    </Group>
+    <Group name="g2">
+        <Enumeration name="shades" basetype="UInt16">
+            <EnumConst name="white" value="1"/>
+            <EnumConst name="light" value="2"/>
+            <EnumConst name="med" value="3"/>
+            <EnumConst name="dark" value="4"/>
+            <EnumConst name="black" value="5"/>
+        </Enumeration>
+        <Enum name="e" enum="/g2/shades"/>
+        <Group name="gg2">
+            <Enum name="e" enum="/g2/shades"/>
+            <Attribute name="test" type="Int16">
+                <Value>1</Value>
+                <Value>2</Value>
+                <Value>3</Value>
+            </Attribute>
+        </Group>
+    </Group>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_6.xml b/unit-tests/D4-xml/DMR_6.xml
new file mode 100644
index 0000000..791ac74
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_6.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_6.xml"    
+    name="DMR_6"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Group name="g1">
+        <Int8 name="i8"/>
+        <Structure name="s">
+            <Int16 name="i16"/>
+            <UInt16 name="ui16"/>
+            <URL name="u"/>
+        </Structure>        
+    </Group>
+    <Group name="g2">
+        <String name="s"/>
+        <Group name="gg2">
+            <Float64 name="f64"/>
+            <Structure name="s">
+                <Int32 name="i16"/>
+                <UInt32 name="ui16"/>
+                <URL name="u"/>
+            </Structure>
+        </Group>
+    </Group>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_6_baseline.xml b/unit-tests/D4-xml/DMR_6_baseline.xml
new file mode 100644
index 0000000..1d972ed
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_6_baseline.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_6.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_6">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+    <Group name="g1">
+        <Int8 name="i8"/>
+        <Structure name="s">
+            <Int16 name="i16"/>
+            <UInt16 name="ui16"/>
+            <URL name="u"/>
+        </Structure>
+    </Group>
+    <Group name="g2">
+        <String name="s"/>
+        <Group name="gg2">
+            <Float64 name="f64"/>
+            <Structure name="s">
+                <Int32 name="i16"/>
+                <UInt32 name="ui16"/>
+                <URL name="u"/>
+            </Structure>
+        </Group>
+    </Group>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_7.1.xml b/unit-tests/D4-xml/DMR_7.1.xml
new file mode 100644
index 0000000..3e06b06
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.1.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_1.xml"    
+    name="DMR_1"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+    <Byte name="a">
+        <Dim name="dim1"/>
+    </Byte>
+    <Char name="a1">
+        <Dim name="dim1"/>
+    </Char>
+    <Int8 name="b">
+        <Dim name="dim1"/>
+    </Int8>
+    <UInt8 name="c">
+        <Dim name="dim1"/>
+        <Dim name="dim2"/>
+    </UInt8>
+    <Int16 name="d">
+        <Dim name="dim1"/>
+    </Int16>
+    <UInt16 name="e">
+        <Dim size="10"/>
+    </UInt16>
+    <Int32 name="f">
+        <Dim name="dim1"/>
+    </Int32>
+    <UInt32 name="g">
+        <Dim name="dim1"/>
+    </UInt32>
+    <Int64 name="h">
+        <Dim name="dim1"/>
+    </Int64>
+    <UInt64 name="i">
+        <Dim name="dim1"/>
+    </UInt64>
+    <Float32 name="j">
+        <Dim name="dim1"/>
+    </Float32>
+    <Float64 name="k">
+        <Dim name="dim1"/>
+    </Float64>
+    
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_7.1_baseline.xml b/unit-tests/D4-xml/DMR_7.1_baseline.xml
new file mode 100644
index 0000000..33899c2
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.1_baseline.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_1.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_1">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+    <Byte name="a">
+        <Dim name="/dim1"/>
+    </Byte>
+    <Char name="a1">
+        <Dim name="/dim1"/>
+    </Char>
+    <Int8 name="b">
+        <Dim name="/dim1"/>
+    </Int8>
+    <UInt8 name="c">
+        <Dim name="/dim1"/>
+        <Dim name="/dim2"/>
+    </UInt8>
+    <Int16 name="d">
+        <Dim name="/dim1"/>
+    </Int16>
+    <UInt16 name="e">
+        <Dim size="10"/>
+    </UInt16>
+    <Int32 name="f">
+        <Dim name="/dim1"/>
+    </Int32>
+    <UInt32 name="g">
+        <Dim name="/dim1"/>
+    </UInt32>
+    <Int64 name="h">
+        <Dim name="/dim1"/>
+    </Int64>
+    <UInt64 name="i">
+        <Dim name="/dim1"/>
+    </UInt64>
+    <Float32 name="j">
+        <Dim name="/dim1"/>
+    </Float32>
+    <Float64 name="k">
+        <Dim name="/dim1"/>
+    </Float64>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_7.2.xml b/unit-tests/D4-xml/DMR_7.2.xml
new file mode 100644
index 0000000..a52c3f8
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.2.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_1.xml"    
+    name="DMR_1"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    
+    <String name="a">
+        <Dim name="dim1"/>
+    </String>
+    <URL name="b">
+        <Dim name="dim1"/>
+    </URL>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_7.2_baseline.xml b/unit-tests/D4-xml/DMR_7.2_baseline.xml
new file mode 100644
index 0000000..a79b45c
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.2_baseline.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_1.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_1">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <String name="a">
+        <Dim name="/dim1"/>
+    </String>
+    <URL name="b">
+        <Dim name="/dim1"/>
+    </URL>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_7.3.xml b/unit-tests/D4-xml/DMR_7.3.xml
new file mode 100644
index 0000000..409ebec
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.3.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_7.3.xml"    
+    name="DMR_1"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    
+    <String name="a">
+        <Dim name="dim1"/>
+    </String>
+    <URL name="b">
+        <Dim name="dim1"/>
+    </URL>
+    
+    <Int8 name="c">
+        <Dim name="dim1"/>
+    </Int8>
+    
+    <UInt8 name="d">
+        <Dim name="dim1"/>
+    </UInt8>
+    
+    <Int64 name="e">
+        <Dim name="dim1"/>
+    </Int64>
+    
+    <UInt64 name="f">
+        <Dim name="dim1"/>
+    </UInt64>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_7.3_baseline.xml b/unit-tests/D4-xml/DMR_7.3_baseline.xml
new file mode 100644
index 0000000..e1df792
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.3_baseline.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_7.3.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_1">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <String name="a">
+        <Dim name="/dim1"/>
+    </String>
+    <URL name="b">
+        <Dim name="/dim1"/>
+    </URL>
+    <Int8 name="c">
+        <Dim name="/dim1"/>
+    </Int8>
+    <UInt8 name="d">
+        <Dim name="/dim1"/>
+    </UInt8>
+    <Int64 name="e">
+        <Dim name="/dim1"/>
+    </Int64>
+    <UInt64 name="f">
+        <Dim name="/dim1"/>
+    </UInt64>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_7.4.xml b/unit-tests/D4-xml/DMR_7.4.xml
new file mode 100644
index 0000000..0a6993f
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.4.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_7.4.xml"    
+    name="DMR_1"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+
+    <Structure name="s">
+        <Dim name="dim1"/>
+
+        <Int32 name="i"/>
+        <Int32 name="j"/> 
+    </Structure>
+
+    <Structure name="t">
+        <Int32 name="i"/>
+            
+        <String name="a">
+            <Dim size="3"/>
+        </String>
+        
+        <Dim name="dim1"/>
+    </Structure>
+
+    <Structure name="u">
+        <Int32 name="i"/>
+        
+        <String name="a">
+            <Dim size="3"/>
+        </String>
+        
+        <Dim name="dim1"/>
+        <Dim name="dim2"/>
+    </Structure>
+    
+    <Structure name="v">
+        <Int32 name="i"/>
+        
+        <String name="a">
+            <Dim size="3"/>
+        </String>
+        
+        <Structure name="w">
+            <Int32 name="i"/>
+            
+            <String name="a">
+                <Dim size="3"/>
+            </String>
+            
+            <Dim name="dim1"/>
+            <Dim name="dim2"/>
+        </Structure>
+        
+        
+        <Dim name="dim1"/>
+        <Dim size="2"/>
+    </Structure>
+    
+    
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_7.4_baseline.xml b/unit-tests/D4-xml/DMR_7.4_baseline.xml
new file mode 100644
index 0000000..6c5d5de
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.4_baseline.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_7.4.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_1">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+    <Structure name="s">
+        <Int32 name="i"/>
+        <Int32 name="j"/>
+        <Dim name="/dim1"/>
+    </Structure>
+    <Structure name="t">
+        <Int32 name="i"/>
+        <String name="a">
+            <Dim size="3"/>
+        </String>
+        <Dim name="/dim1"/>
+    </Structure>
+    <Structure name="u">
+        <Int32 name="i"/>
+        <String name="a">
+            <Dim size="3"/>
+        </String>
+        <Dim name="/dim1"/>
+        <Dim name="/dim2"/>
+    </Structure>
+    <Structure name="v">
+        <Int32 name="i"/>
+        <String name="a">
+            <Dim size="3"/>
+        </String>
+        <Structure name="w">
+            <Int32 name="i"/>
+            <String name="a">
+                <Dim size="3"/>
+            </String>
+            <Dim name="/dim1"/>
+            <Dim name="/dim2"/>
+        </Structure>
+        <Dim name="/dim1"/>
+        <Dim size="2"/>
+    </Structure>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_7.5.xml b/unit-tests/D4-xml/DMR_7.5.xml
new file mode 100644
index 0000000..8ea8ed2
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.5.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_1.xml"    
+    name="DMR_1"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    
+    <Enum name="e" enum="colors">
+        <Dim name="dim1"/>
+    </Enum>
+    
+    <Opaque name="o">
+        <Dim name="dim1"/>
+    </Opaque>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_7.5_baseline.xml b/unit-tests/D4-xml/DMR_7.5_baseline.xml
new file mode 100644
index 0000000..ab6537d
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.5_baseline.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_1.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_1">
+    <Dimension name="dim1" size="5"/>
+    <Dimension name="dim2" size="3"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Enum name="e" enum="/colors">
+        <Dim name="/dim1"/>
+    </Enum>
+    <Opaque name="o">
+        <Dim name="/dim1"/>
+    </Opaque>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_7.xml b/unit-tests/D4-xml/DMR_7.xml
new file mode 100644
index 0000000..2f354d0
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_1.xml"    
+    name="DMR_1"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Byte name="b1">
+        <Dim name="dim1"/>
+    </Byte>
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_7_baseline.xml b/unit-tests/D4-xml/DMR_7_baseline.xml
new file mode 100644
index 0000000..444446b
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_7_baseline.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_1.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_1">
+    <Dimension name="dim1" size="5"/>
+    <Byte name="b1">
+        <Dim name="/dim1"/>
+    </Byte>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_8.xml b/unit-tests/D4-xml/DMR_8.xml
new file mode 100644
index 0000000..f2e1696
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_8.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_8.xml"    
+    name="DMR_8"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="x-axis" size="5"/>
+    <Float32 name="x">
+        <Dim name="x-axis"/>
+    </Float32>
+    
+    <Byte name="b1">
+        <Dim name="x-axis"/>
+        <Map name="x"/>
+    </Byte>
+    
+</Dataset>   
diff --git a/unit-tests/D4-xml/DMR_8_baseline.xml b/unit-tests/D4-xml/DMR_8_baseline.xml
new file mode 100644
index 0000000..840138b
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_8_baseline.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_8.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_8">
+    <Dimension name="x-axis" size="5"/>
+    <Float32 name="x">
+        <Dim name="/x-axis"/>
+    </Float32>
+    <Byte name="b1">
+        <Dim name="/x-axis"/>
+        <Map name="/x"/>
+    </Byte>
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_empty.xml b/unit-tests/D4-xml/DMR_empty.xml
new file mode 100644
index 0000000..de5758f
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_empty.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- This is the smallest DMR possible -->
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_empty.xml"
+    name="DMR_empty" dapVersion="4.0" dmrVersion="1.0">
+    
+</Dataset>
diff --git a/unit-tests/D4-xml/DMR_empty_baseline.xml b/unit-tests/D4-xml/DMR_empty_baseline.xml
new file mode 100644
index 0000000..d862eca
--- /dev/null
+++ b/unit-tests/D4-xml/DMR_empty_baseline.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" xml:base="file:DMR_empty.xml" dapVersion="4.0" dmrVersion="1.0" name="DMR_empty"/>
diff --git a/unit-tests/D4-xml/Data_DMR_3.xml b/unit-tests/D4-xml/Data_DMR_3.xml
new file mode 100644
index 0000000..d68ebf1
--- /dev/null
+++ b/unit-tests/D4-xml/Data_DMR_3.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" 
+    xml:base="file:DMR_3.xml"    
+    name="DMR_3"
+    dapVersion="4.0"
+    dmrVersion="1.0">
+    <Dimension name="dim1" size="5"/>
+    <Enumeration name="colors" basetype="Byte">
+        <EnumConst name="red" value="1"/>
+        <EnumConst name="green" value="2"/>
+        <EnumConst name="blue" value="3"/>
+    </Enumeration>
+    <Byte name="b1"/>
+</Dataset>
+
+
+some more binary goo...
diff --git a/unit-tests/D4-xml/README b/unit-tests/D4-xml/README
index 5cef568..c54a66b 100644
--- a/unit-tests/D4-xml/README
+++ b/unit-tests/D4-xml/README
@@ -5,3 +5,6 @@ README
 
 This directory holds xml files that are the baselines for various unit test
 for the new DAP4 types and ancillary classes.
+
+And some other stuff I've added... 10/15/14
+
diff --git a/unit-tests/D4-xml/coads_climatology.nc.xml b/unit-tests/D4-xml/coads_climatology.nc.xml
new file mode 100644
index 0000000..06c4f3e
--- /dev/null
+++ b/unit-tests/D4-xml/coads_climatology.nc.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="coads_climatology.nc">
+    <Dimension name="TIME" size="12"/>
+    <Dimension name="COADSY" size="90"/>
+    <Dimension name="COADSX" size="180"/>
+    <Float64 name="TIME">
+        <Dim name="/TIME"/>
+    </Float64>
+    <Float64 name="COADSY">
+        <Dim name="/COADSY"/>
+    </Float64>
+    <Float64 name="COADSX">
+        <Dim name="/COADSX"/>
+    </Float64>
+    <Float32 name="SST">
+        <Dim name="/TIME"/>
+        <Dim name="/COADSY"/>
+        <Dim name="/COADSX"/>
+        <Attribute name="missing_value" type="Byte">
+            <Value>-9.999999790e+33</Value>
+        </Attribute>
+        <Attribute name="_FillValue" type="Byte">
+            <Value>-9.999999790e+33</Value>
+        </Attribute>
+        <Attribute name="long_name" type="String">
+            <Value>SEA SURFACE TEMPERATURE</Value>
+        </Attribute>
+        <Attribute name="history" type="String">
+            <Value>From coads_climatology</Value>
+        </Attribute>
+        <Attribute name="units" type="String">
+            <Value>Deg C</Value>
+        </Attribute>
+        <Map name="TIME"/>
+        <Map name="COADSY"/>
+        <Map name="COADSX"/>
+    </Float32>
+    <Float32 name="AIRT">
+        <Dim name="/TIME"/>
+        <Dim name="/COADSY"/>
+        <Dim name="/COADSX"/>
+        <Attribute name="missing_value" type="Byte">
+            <Value>-9.999999790e+33</Value>
+        </Attribute>
+        <Attribute name="_FillValue" type="Byte">
+            <Value>-9.999999790e+33</Value>
+        </Attribute>
+        <Attribute name="long_name" type="String">
+            <Value>AIR TEMPERATURE</Value>
+        </Attribute>
+        <Attribute name="history" type="String">
+            <Value>From coads_climatology</Value>
+        </Attribute>
+        <Attribute name="units" type="String">
+            <Value>DEG C</Value>
+        </Attribute>
+        <Map name="TIME"/>
+        <Map name="COADSY"/>
+        <Map name="COADSX"/>
+    </Float32>
+    <Float32 name="UWND">
+        <Dim name="/TIME"/>
+        <Dim name="/COADSY"/>
+        <Dim name="/COADSX"/>
+        <Attribute name="missing_value" type="Byte">
+            <Value>-9.999999790e+33</Value>
+        </Attribute>
+        <Attribute name="_FillValue" type="Byte">
+            <Value>-9.999999790e+33</Value>
+        </Attribute>
+        <Attribute name="long_name" type="String">
+            <Value>ZONAL WIND</Value>
+        </Attribute>
+        <Attribute name="history" type="String">
+            <Value>From coads_climatology</Value>
+        </Attribute>
+        <Attribute name="units" type="String">
+            <Value>M/S</Value>
+        </Attribute>
+        <Map name="TIME"/>
+        <Map name="COADSY"/>
+        <Map name="COADSX"/>
+    </Float32>
+    <Float32 name="VWND">
+        <Dim name="/TIME"/>
+        <Dim name="/COADSY"/>
+        <Dim name="/COADSX"/>
+        <Attribute name="missing_value" type="Byte">
+            <Value>-9.999999790e+33</Value>
+        </Attribute>
+        <Attribute name="_FillValue" type="Byte">
+            <Value>-9.999999790e+33</Value>
+        </Attribute>
+        <Attribute name="long_name" type="String">
+            <Value>MERIDIONAL WIND</Value>
+        </Attribute>
+        <Attribute name="history" type="String">
+            <Value>From coads_climatology</Value>
+        </Attribute>
+        <Attribute name="units" type="String">
+            <Value>M/S</Value>
+        </Attribute>
+        <Map name="TIME"/>
+        <Map name="COADSY"/>
+        <Map name="COADSX"/>
+    </Float32>
+    <Attribute name="NC_GLOBAL" type="Container">
+        <Attribute name="history" type="String">
+            <Value>FERRET V4.30 (debug/no GUI) 15-Aug-96</Value>
+        </Attribute>
+    </Attribute>
+    <Attribute name="DODS_EXTRA" type="Container">
+        <Attribute name="Unlimited_Dimension" type="String">
+            <Value>TIME</Value>
+        </Attribute>
+    </Attribute>
+</Dataset>
+
diff --git a/unit-tests/D4AsyncDocTest.cc b/unit-tests/D4AsyncDocTest.cc
new file mode 100644
index 0000000..6ef042b
--- /dev/null
+++ b/unit-tests/D4AsyncDocTest.cc
@@ -0,0 +1,347 @@
+// -*- 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>
+
+//#define DODS_DEBUG
+
+#include <GetOpt.h>
+#include <GNURegex.h>
+#include <util.h>
+#include <debug.h>
+
+#include "D4AsyncUtil.h"
+#include "XMLWriter.h"
+#include "debug.h"
+
+#include "testFile.h"
+#include "test_config.h"
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
+
+class D4AsyncDocTest: public TestFixture {
+private:
+    XMLWriter *xml;
+
+public:
+    D4AsyncDocTest(): xml(0) {
+    }
+
+    ~D4AsyncDocTest() {
+    }
+
+    void setUp() {
+        xml = new XMLWriter;
+
+    }
+
+    void tearDown() {
+        delete xml;
+    }
+
+    // An empty D4Dimensions object prints nothing; the XMLWriter class adds
+    // a xml doc preface.
+    void test_async_required() {
+        DBG(cerr << endl << " ---- test_async_required - BEGIN" << endl);
+
+    	D4AsyncUtil dau;
+        DBG(cerr << endl);
+
+        string *stylesheet_ref=0;
+
+    	dau.writeD4AsyncRequired(*xml, 6001, 600007, stylesheet_ref);
+
+        string doc = xml->get_doc();
+        DBG(cerr << "[test_async_required - candidate doc]" << endl << doc << endl);
+
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncRequired.xml");
+        DBG(cerr << "[test_async_required - baseline doc]" << endl << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+
+        DBG(cerr << endl << " ---- test_async_required - END" << endl);
+    }
+
+    // An empty D4Dimensions object prints nothing; the XMLWriter class adds
+    // a xml doc preface.
+    void test_async_required_with_stylesheet_ref() {
+        DBG(cerr << endl << " ---- test_async_required - BEGIN" << endl);
+
+    	D4AsyncUtil dau;
+        DBG(cerr << endl);
+
+        string stylesheet_ref =  "http://someServer:8080/opendap/xsl/asyncResponse.xsl";
+
+    	dau.writeD4AsyncRequired(*xml, 6001, 600007, &stylesheet_ref);
+
+        string doc = xml->get_doc();
+        DBG(cerr << "[test_async_required - candidate doc]" << endl << doc << endl);
+
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncRequired_StyleRef.xml");
+        DBG(cerr << "[test_async_required - baseline doc]" << endl << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+
+        DBG(cerr << endl << " ---- test_async_required - END" << endl);
+    }
+
+    // An empty D4Dimensions object prints nothing; the XMLWriter class adds
+     // a xml doc preface.
+     void test_async_accepted() {
+         DBG(cerr << endl << " ---- test_async_accepted - BEGIN" << endl);
+
+     	D4AsyncUtil dau;
+         DBG(cerr << endl);
+
+         string stylesheet_ref =  "http://someServer:8080/opendap/xsl/asyncResponse.xsl";
+
+     	dau.writeD4AsyncAccepted(*xml, 6003, 600009,"http://test.opendap.org:8080/opendap/storedResults/result_87697163.dap");
+
+         string doc = xml->get_doc();
+         DBG(cerr << "[test_async_accepted - candidate doc]" << endl << doc << endl);
+
+         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncAccepted.xml");
+         DBG(cerr << "[test_async_accepted - baseline doc]" << endl << baseline << endl);
+         CPPUNIT_ASSERT(doc == baseline);
+         DBG(cerr << endl << " ---- test_async_accepted - END" << endl);
+     }
+
+     // An empty D4Dimensions object prints nothing; the XMLWriter class adds
+      // a xml doc preface.
+      void test_async_accepted_with_stylesheet_ref() {
+          DBG(cerr << endl << " ---- test_async_accepted - BEGIN" << endl);
+
+      	D4AsyncUtil dau;
+          DBG(cerr << endl);
+          string stylesheet_ref =  "http://someServer:8080/opendap/xsl/asyncResponse.xsl";
+
+      	dau.writeD4AsyncAccepted(*xml, 6003, 600009,"http://test.opendap.org:8080/opendap/storedResults/result_87697163.dap", &stylesheet_ref);
+
+          string doc = xml->get_doc();
+          DBG(cerr << "[test_async_accepted - candidate doc]" << endl << doc << endl);
+
+          string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncAccepted_StyleRef.xml");
+          DBG(cerr << "[test_async_accepted - baseline doc]" << endl << baseline << endl);
+          CPPUNIT_ASSERT(doc == baseline);
+          DBG(cerr << endl << " ---- test_async_accepted - END" << endl);
+      }
+
+
+      // An empty D4Dimensions object prints nothing; the XMLWriter class adds
+      // a xml doc preface.
+      void test_async_pending() {
+          DBG(cerr << endl << " ---- test_async_pending - BEGIN" << endl);
+
+      	D4AsyncUtil dau;
+          DBG(cerr << endl);
+
+          dau.writeD4AsyncPending(*xml);
+
+          string doc = xml->get_doc();
+          DBG(cerr << "[test_async_pending - candidate doc]" << endl << doc << endl);
+
+          string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncPending.xml");
+          DBG(cerr << "[test_async_pending - baseline doc]" << endl << baseline << endl);
+          CPPUNIT_ASSERT(doc == baseline);
+          DBG(cerr << endl << " ---- test_async_pending - END" << endl);
+      }
+
+
+
+      // An empty D4Dimensions object prints nothing; the XMLWriter class adds
+      // a xml doc preface.
+      void test_async_pending_with_stylesheet_ref() {
+          DBG(cerr << endl << " ---- test_async_pending - BEGIN" << endl);
+
+      	D4AsyncUtil dau;
+          DBG(cerr << endl);
+          string stylesheet_ref =  "http://someServer:8080/opendap/xsl/asyncResponse.xsl";
+
+      	dau.writeD4AsyncPending(*xml, &stylesheet_ref);
+
+          string doc = xml->get_doc();
+          DBG(cerr << "[test_async_pending - candidate doc]" << endl << doc << endl);
+
+          string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncPending_StyleRef.xml");
+          DBG(cerr << "[test_async_pending - baseline doc]" << endl << baseline << endl);
+          CPPUNIT_ASSERT(doc == baseline);
+          DBG(cerr << endl << " ---- test_async_pending - END" << endl);
+      }
+
+      // An empty D4Dimensions object prints nothing; the XMLWriter class adds
+      // a xml doc preface.
+      void test_async_ResponseGone() {
+          DBG(cerr << endl << " ---- test_async_ResponseGone - BEGIN" << endl);
+
+      	D4AsyncUtil dau;
+          DBG(cerr << endl);
+
+      	dau.writeD4AsyncResponseGone(*xml);
+
+          string doc = xml->get_doc();
+          DBG(cerr << "[test_async_ResponseGone - candidate doc]" << endl << doc << endl);
+
+          string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncGone.xml");
+          DBG(cerr << "[test_async_ResponseGone - baseline doc]" << endl << baseline << endl);
+          CPPUNIT_ASSERT(doc == baseline);
+          DBG(cerr << endl << " ---- test_async_ResponseGone - END" << endl);
+      }
+
+	// An empty D4Dimensions object prints nothing; the XMLWriter class adds
+	// a xml doc preface.
+	void test_async_ResponseGone_with_stylesheet_ref() {
+		DBG(cerr << endl << " ---- test_async_ResponseGone - BEGIN" << endl);
+
+		D4AsyncUtil dau;
+		DBG(cerr << endl);
+		string stylesheet_ref =  "http://someServer:8080/opendap/xsl/asyncResponse.xsl";
+
+		dau.writeD4AsyncResponseGone(*xml, &stylesheet_ref);
+
+		string doc = xml->get_doc();
+		DBG(cerr << "[test_async_ResponseGone - candidate doc]" << endl << doc << endl);
+
+		string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncGone_StyleRef.xml");
+		DBG(cerr << "[test_async_ResponseGone - baseline doc]" << endl << baseline << endl);
+		CPPUNIT_ASSERT(doc == baseline);
+		DBG(cerr << endl << " ---- test_async_ResponseGone - END" << endl);
+	}
+
+
+	// An empty D4Dimensions object prints nothing; the XMLWriter class adds
+	// a xml doc preface.
+	void test_async_ResponseRejected() {
+
+		D4AsyncUtil dau;
+		DBG(cerr << endl << " ---- test_async_ResponseRejected - BEGIN" << endl);
+
+		dau.writeD4AsyncResponseRejected(*xml, TIME,"The time to process your request is longer than the time you indicated was acceptable.");
+
+		string doc = xml->get_doc();
+		DBG(cerr << "[test_async_ResponseRejected - candidate doc]" << endl << doc << endl);
+
+		string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncRejected.xml");
+		DBG(cerr << "[test_async_ResponseRejected - baseline doc]" << endl << baseline << endl);
+		CPPUNIT_ASSERT(doc == baseline);
+
+		DBG(cerr << endl << " ---- test_async_ResponseRejected - END" << endl);
+	}
+
+
+
+      // An empty D4Dimensions object prints nothing; the XMLWriter class adds
+      // a xml doc preface.
+      void test_async_ResponseRejected_with_stylesheet_ref() {
+
+      	D4AsyncUtil dau;
+          DBG(cerr << endl << " ---- test_async_ResponseRejected - BEGIN" << endl);
+          string stylesheet_ref =  "http://someServer:8080/opendap/xsl/asyncResponse.xsl";
+
+      	dau.writeD4AsyncResponseRejected(*xml, TIME,"The time to process your request is longer than the time you indicated was acceptable.", &stylesheet_ref);
+
+          string doc = xml->get_doc();
+          DBG(cerr << "[test_async_ResponseRejected - candidate doc]" << endl << doc << endl);
+
+          string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4AsyncRejected_StyleRef.xml");
+          DBG(cerr << "[test_async_ResponseRejected - baseline doc]" << endl << baseline << endl);
+          CPPUNIT_ASSERT(doc == baseline);
+
+          DBG(cerr << endl << " ---- test_async_ResponseRejected - END" << endl);
+      }
+
+
+    CPPUNIT_TEST_SUITE( D4AsyncDocTest );
+
+	CPPUNIT_TEST(test_async_required);
+	CPPUNIT_TEST(test_async_required_with_stylesheet_ref);
+	CPPUNIT_TEST(test_async_accepted);
+	CPPUNIT_TEST(test_async_accepted_with_stylesheet_ref);
+	CPPUNIT_TEST(test_async_pending);
+	CPPUNIT_TEST(test_async_pending_with_stylesheet_ref);
+	CPPUNIT_TEST(test_async_ResponseGone);
+	CPPUNIT_TEST(test_async_ResponseGone_with_stylesheet_ref);
+	CPPUNIT_TEST(test_async_ResponseRejected);
+	CPPUNIT_TEST(test_async_ResponseRejected_with_stylesheet_ref);
+
+	CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(D4AsyncDocTest);
+
+int main(int argc, char*argv[]) {
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = 1;  // debug is a static global
+            break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("D4AsyncDocTest::") + argv[i++];
+
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
+    return wasSuccessful ? 0 : 1;
+}
+
+
+
+#if 0
+
+int main(int, char**) {
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    bool wasSuccessful = runner.run("", false);
+
+    return wasSuccessful ? 0 : 1;
+}
+#endif
diff --git a/unit-tests/D4AttributesTest.cc b/unit-tests/D4AttributesTest.cc
new file mode 100644
index 0000000..b7b86a4
--- /dev/null
+++ b/unit-tests/D4AttributesTest.cc
@@ -0,0 +1,308 @@
+// -*- 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>
+
+//#define DODS_DEBUG
+
+#include "D4Attributes.h"
+#include "XMLWriter.h"
+#include "debug.h"
+
+#include "testFile.h"
+#include "test_config.h"
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
+class D4AttributesTest: public TestFixture {
+private:
+    XMLWriter *xml;
+    D4Attributes *attrs;
+
+    D4Attribute a, a2, a3, a4, a5, c, c2;
+
+public:
+    D4AttributesTest() {
+    }
+
+    ~D4AttributesTest() {
+    }
+
+    void setUp() {
+        attrs = new D4Attributes;
+        xml = new XMLWriter;
+
+        a.set_name("first");
+        a.set_type(attr_byte_c);
+        a.add_value("1");
+        a.add_value("2");
+
+        a2.set_name("second");
+        a2.set_type(attr_int32_c);
+        a2.add_value("10000");
+
+        c.set_name("container_1");
+        c.set_type(attr_container_c);
+
+        a3.set_name("color");
+        a3.set_type(attr_str_c);
+        vector<string> colors; colors.push_back("red"); colors.push_back("blue");  colors.push_back("green");
+        a3.add_value_vector(colors);
+
+        a4 = a2;
+        a4.set_name("control");
+
+        c.attributes()->add_attribute(&a3);
+
+        c2.set_name("container_2");
+        c2.set_type(attr_container_c);
+
+        c2.attributes()->add_attribute(&a4);
+        c2.attributes()->add_attribute(&c);
+    }
+
+    void tearDown() {
+        delete xml;
+        delete attrs;
+    }
+
+    // An empty D4Dimensions object prints nothing; the XMLWriter class adds
+    // a xml doc preface.
+    void test_print_empty() {
+        attrs->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Attributes_empty.xml");
+        DBG(cerr << "D4Attributes: " << doc << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_single_attribute() {
+        a.print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Attributes_values_1.xml");
+        DBG(cerr << "D4Attributes: " << doc << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+
+    }
+
+    void test_print_1() {
+        attrs->add_attribute(&a);
+
+        attrs->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Attributes_1.xml");
+        DBG(cerr << "D4Attributes: " << doc << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+
+    void test_print_2() {
+        attrs->add_attribute(&a);
+        attrs->add_attribute(&a2);
+
+        attrs->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Attributes_2.xml");
+        DBG(cerr << "D4Attributes: " << doc << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_3() {
+        attrs->add_attribute(&a);
+        attrs->add_attribute(&a2);
+        attrs->add_attribute(&c);
+        attrs->add_attribute(&c2);
+
+        attrs->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Attributes_3.xml");
+        DBG(cerr << "D4Attributes: " << doc << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_assignment() {
+        attrs->add_attribute(&a);
+        attrs->add_attribute(&a2);
+
+        D4Attributes lhs = *attrs;
+
+        lhs.print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Attributes_assignment.xml");
+        DBG(cerr << "D4Attributes: " << doc << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_assignment_2() {
+        attrs->add_attribute(&a);
+        attrs->add_attribute(&a2);
+        attrs->add_attribute(&c);
+        attrs->add_attribute(&c2);
+
+        D4Attributes lhs = *attrs;
+
+        lhs.print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Attributes_assignment_2.xml");
+        DBG(cerr << "D4Attributes: " << doc << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_copy_ctor() {
+        attrs->add_attribute(&a);
+        attrs->add_attribute(&a2);
+
+        D4Attributes lhs(*attrs);
+
+        lhs.print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Attributes_copy_ctor.xml");
+        DBG(cerr << "D4Attributes: " << doc << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_find() {
+        attrs->add_attribute(&a);
+        attrs->add_attribute(&a2);
+        attrs->add_attribute(&c);
+        attrs->add_attribute(&c2);
+
+        D4Attribute *find_result = attrs->find("color");
+
+        // 'color' is in the container 'container' which is the third
+        // attribute
+        D4Attribute *baseline = *(attrs->attribute_begin() + 2);
+        CPPUNIT_ASSERT(baseline);
+        CPPUNIT_ASSERT(baseline->type() == attr_container_c);
+        D4Attributes *local_attrs = baseline->attributes();
+
+        // it is the first attribute in that container
+        baseline = *(local_attrs->attribute_begin());
+        CPPUNIT_ASSERT(baseline);
+        CPPUNIT_ASSERT(baseline->type() == attr_str_c);
+        CPPUNIT_ASSERT(baseline->name() == "color");
+
+        // We get a pointer to actual container, not a copy
+        CPPUNIT_ASSERT(baseline == find_result);
+    }
+
+    void test_get() {
+        attrs->add_attribute(&a);
+        attrs->add_attribute(&a2);
+        attrs->add_attribute(&c);
+        attrs->add_attribute(&c2);
+
+        D4Attribute *get_result = attrs->get("container_1.color");
+
+        // 'color' is in the container 'container_1' which is the third
+        // attribute
+        D4Attribute *baseline = *(attrs->attribute_begin() + 2);
+        CPPUNIT_ASSERT(baseline);
+        CPPUNIT_ASSERT(baseline->type() == attr_container_c);
+        D4Attributes *local_attrs = baseline->attributes();
+
+        // it is the first attribute in that container
+        baseline = *(local_attrs->attribute_begin());
+        CPPUNIT_ASSERT(baseline);
+        CPPUNIT_ASSERT(baseline->type() == attr_str_c);
+        CPPUNIT_ASSERT(baseline->name() == "color");
+
+        // We get a pointer to actual container, not a copy
+        CPPUNIT_ASSERT(baseline == get_result);
+    }
+
+    void test_get2() {
+        attrs->add_attribute(&a);
+        attrs->add_attribute(&a2);
+        attrs->add_attribute(&c);
+        attrs->add_attribute(&c2);
+
+        D4Attribute *get_result = attrs->get("container_2.container_1.color");
+
+        // 'color' is (also) in the container 'container_1' which is in
+        // the container 'container_2' which is the fourth attribute
+        D4Attribute *baseline = *(attrs->attribute_begin() + 3);
+        CPPUNIT_ASSERT(baseline);
+        CPPUNIT_ASSERT(baseline->type() == attr_container_c);
+        CPPUNIT_ASSERT(baseline->name() == "container_2");
+        D4Attributes *local_attrs = baseline->attributes();
+
+        // 'container_1 is the second attribute in 'container_2'
+        baseline = *(local_attrs->attribute_begin() + 1);
+        CPPUNIT_ASSERT(baseline);
+        CPPUNIT_ASSERT(baseline->type() == attr_container_c);
+        CPPUNIT_ASSERT(baseline->name() == "container_1");
+        local_attrs = baseline->attributes();
+
+        // finally, 'color' is the first attribute in 'container_1'
+        baseline = *(local_attrs->attribute_begin());
+        CPPUNIT_ASSERT(baseline->type() == attr_str_c);
+        CPPUNIT_ASSERT(baseline->name() == "color");
+
+        // We get a pointer to actual container, not a copy
+        CPPUNIT_ASSERT(baseline == get_result);
+    }
+
+    CPPUNIT_TEST_SUITE( D4AttributesTest );
+
+        CPPUNIT_TEST(test_print_empty);
+        CPPUNIT_TEST(test_print_single_attribute);
+        CPPUNIT_TEST(test_print_1);
+        CPPUNIT_TEST(test_print_2);
+        CPPUNIT_TEST(test_print_3);
+
+        CPPUNIT_TEST(test_print_assignment);
+        CPPUNIT_TEST(test_print_assignment_2);
+
+        CPPUNIT_TEST(test_print_copy_ctor);
+
+        CPPUNIT_TEST(test_find);
+        CPPUNIT_TEST(test_get);
+        CPPUNIT_TEST(test_get2);
+
+        CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(D4AttributesTest);
+
+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/D4DimensionsTest.cc b/unit-tests/D4DimensionsTest.cc
index b30ad9b..17fcd08 100644
--- a/unit-tests/D4DimensionsTest.cc
+++ b/unit-tests/D4DimensionsTest.cc
@@ -28,10 +28,14 @@
 #include <cppunit/extensions/TestFactoryRegistry.h>
 #include <cppunit/extensions/HelperMacros.h>
 
+#include <GetOpt.h> // Part of libdap
+
 //#define DODS_DEBUG
 
 #include "D4Dimensions.h"
 #include "XMLWriter.h"
+
+#include "Error.h"
 #include "debug.h"
 
 #include "testFile.h"
@@ -41,13 +45,18 @@ using namespace CppUnit;
 using namespace std;
 using namespace libdap;
 
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
 class D4DimensionsTest: public TestFixture {
 private:
     XMLWriter *xml;
     D4Dimensions *d;
 
 public:
-    D4DimensionsTest() {
+    D4DimensionsTest() : xml(0), d(0) {
     }
 
     ~D4DimensionsTest() {
@@ -66,7 +75,7 @@ public:
     // An empty D4Dimensions object prints nothing; the XMLWriter class adds
     // a xml doc preface.
     void test_print_empty() {
-        d->print(*xml);
+        d->print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Dimensions_empty.xml");
         DBG(cerr << "test_print_empty: doc: " << doc << endl);
@@ -75,9 +84,9 @@ public:
     }
 
     void test_print_1() {
-        d->add_dim("first", 10);
+        d->add_dim_nocopy(new D4Dimension("first", 10));
 
-        d->print(*xml);
+        d->print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Dimensions_1.xml");
         DBG(cerr << "test_print_1: doc: " << doc << endl);
@@ -86,10 +95,10 @@ public:
     }
 
     void test_print_2() {
-        d->add_dim("first", 10);
-        d->add_dim("second", 100);
+        d->add_dim_nocopy(new D4Dimension("first", 10));
+        d->add_dim_nocopy(new D4Dimension("second", 100));
 
-        d->print(*xml);
+        d->print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Dimensions_2.xml");
         DBG(cerr << "test_print_2: doc: " << doc << endl);
@@ -97,29 +106,63 @@ public:
         CPPUNIT_ASSERT(doc == baseline);
     }
 
+    void test_error() {
+        D4Dimension *d3, *d2;
+        try {
+            d2 = new D4Dimension();
+            d2->set_name("error");
+            d2->set_size("10");
+
+            d3 = new D4Dimension();
+            d3->set_name("error");
+            d3->set_size("20.0");
+            delete d3; delete d2;
+            CPPUNIT_FAIL("Should throw an Error");
+        }
+        catch(...) {
+            delete d3; delete d2;
+            throw;
+        }
+    }
+
+    void test_error_2() {
+        D4Dimension *d3;
+        try {
+            d3 = new D4Dimension();
+            d3->set_name("error");
+            d3->set_size("bad");
+            delete d3;
+            CPPUNIT_FAIL("Should throw an Error");
+        }
+        catch(...) {
+            delete d3;
+            throw;
+        }
+    }
+#ifdef VARYING
     void test_print_varying() {
-        d->add_dim("first", 10);
-        d->add_dim("second", 100);
-        d->add_dim("third", 0, true);
+        d->add_dim_nocopy(new D4Dimension("first", 10));
+        d->add_dim_nocopy(new D4Dimension("second", 100));
+        d->add_dim_nocopy(new D4Dimension("third"));
 
-        d->print(*xml);
+        d->print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Dimensions_3.xml");
         DBG(cerr << "test_print_varying: doc: " << doc << endl);
         DBG(cerr << "test_print_varying: baseline: " << baseline << endl);
         CPPUNIT_ASSERT(doc == baseline);
     }
-
+#endif
     void test_print_insert_dim() {
-        d->add_dim("first", 10);
-        d->add_dim("second", 100);
-        d->add_dim("third", 0, true);
+        d->add_dim_nocopy(new D4Dimension("first", 10));
+        d->add_dim_nocopy(new D4Dimension("second", 100));
+        d->add_dim_nocopy(new D4Dimension("third", 1000));
 
         //vector<D4Dimensions::dimension>::iterator i = d->dim_begin() + 1;
         D4Dimensions::D4DimensionsIter i = d->dim_begin() + 1;
-        d->insert_dim("odd", 20, false /*varying*/, i);
+        d->insert_dim_nocopy(new D4Dimension("odd", 20), i);
 
-        d->print(*xml);
+        d->print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Dimensions_4.xml");
         DBG(cerr << "test_print_insert_dim: doc: " << doc << endl);
@@ -128,13 +171,13 @@ public:
     }
 
     void test_print_assignment() {
-        d->add_dim("first", 10);
-        d->add_dim("second", 100);
-        d->add_dim("third", 0, true);
+        d->add_dim_nocopy(new D4Dimension("first", 10));
+        d->add_dim_nocopy(new D4Dimension("second", 100));
+        d->add_dim_nocopy(new D4Dimension("third", 1000));
 
         D4Dimensions lhs = *d;
 
-        lhs.print(*xml);
+        lhs.print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Dimensions_3.xml");
         DBG(cerr << "test_print_assignment: doc: " << doc << endl);
@@ -143,13 +186,13 @@ public:
     }
 
     void test_print_copy_ctor() {
-        d->add_dim("first", 10);
-        d->add_dim("second", 100);
-        d->add_dim("third", 0, true);
+        d->add_dim_nocopy(new D4Dimension("first", 10));
+        d->add_dim_nocopy(new D4Dimension("second", 100));
+        d->add_dim_nocopy(new D4Dimension("third", 1000));
 
         D4Dimensions lhs(*d);
 
-        lhs.print(*xml);
+        lhs.print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Dimensions_3.xml");
         DBG(cerr << "test_print_copy_ctor: doc: " << doc << endl);
@@ -162,7 +205,13 @@ public:
         CPPUNIT_TEST(test_print_empty);
         CPPUNIT_TEST(test_print_1);
         CPPUNIT_TEST(test_print_2);
+
+        CPPUNIT_TEST_EXCEPTION( test_error, Error );
+        //CPPUNIT_TEST( test_error );
+        CPPUNIT_TEST_EXCEPTION( test_error_2, Error );
+#ifdef VARYING
         CPPUNIT_TEST(test_print_varying);
+#endif
         CPPUNIT_TEST(test_print_insert_dim);
         CPPUNIT_TEST(test_print_assignment);
         CPPUNIT_TEST(test_print_copy_ctor);
@@ -172,11 +221,36 @@ public:
 
 CPPUNIT_TEST_SUITE_REGISTRATION(D4DimensionsTest);
 
-int main(int, char**) {
+int main(int argc, char*argv[]) {
     CppUnit::TextTestRunner runner;
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
 
-    bool wasSuccessful = runner.run("", false);
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = 1;  // debug is a static global
+            break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("D4DimensionsTest::") + argv[i++];
+
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
 
     return wasSuccessful ? 0 : 1;
 }
diff --git a/unit-tests/D4EnumDefsTest.cc b/unit-tests/D4EnumDefsTest.cc
index dfea4b3..bada5c9 100644
--- a/unit-tests/D4EnumDefsTest.cc
+++ b/unit-tests/D4EnumDefsTest.cc
@@ -46,7 +46,7 @@ private:
     XMLWriter *xml;
     D4EnumDefs *d;
 
-    enumValues e, e2;
+    D4EnumDef e, e2;
 
 public:
     D4EnumDefsTest() {
@@ -59,9 +59,13 @@ public:
         d = new D4EnumDefs;
         xml = new XMLWriter;
 
+        e.set_name("first");
+        e.set_type(dods_byte_c);
         e.add_value("red", 1);
         e.add_value("blue", 2);
 
+        e2.set_name("second");
+        e2.set_type(dods_int32_c);
         e2.add_value("snow", 0);
         e2.add_value("ice", 10000);
     }
@@ -74,7 +78,7 @@ public:
     // An empty D4Dimensions object prints nothing; the XMLWriter class adds
     // a xml doc preface.
     void test_print_empty() {
-        d->print(*xml);
+        d->print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4EnumDefs_empty.xml");
         DBG(cerr << "test_print_empty: doc: " << doc << endl);
@@ -83,11 +87,11 @@ public:
     }
 
     void test_print_enum_values_only() {
-        enumValues e;
+        D4EnumDef e;
         e.add_value("red", 1);
         e.add_value("blue", 2);
 
-        e.print(*xml);
+        e.print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4EnumDefs_values_1.xml");
         DBG(cerr << "test_print_enum_values_only: doc: " << doc << endl);
@@ -97,9 +101,9 @@ public:
     }
 
     void test_print_1() {
-        d->add_enum("first", dods_byte_c, e);
+        d->add_enum(&e);
 
-        d->print(*xml);
+        d->print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4EnumDefs_1.xml");
         DBG(cerr << "test_print_1: doc: " << doc << endl);
@@ -109,10 +113,10 @@ public:
 
 
     void test_print_2() {
-        d->add_enum("first", dods_byte_c, e);
-        d->add_enum("second", dods_int32_c, e2);
+        d->add_enum(&e);
+        d->add_enum(&e2);
 
-        d->print(*xml);
+        d->print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4EnumDefs_2.xml");
         DBG(cerr << "test_print_2: doc: " << doc << endl);
@@ -121,13 +125,13 @@ public:
     }
 
     void test_print_insert_enum() {
-        d->add_enum("first", dods_byte_c, e);
+        d->add_enum(&e);
 
         // "second' winds up before 'first'
-        D4EnumDefs::D4EnumIter i = d->enum_begin();
-        d->insert_enum("second", dods_int32_c, e2, i);
+        D4EnumDefs::D4EnumDefIter i = d->enum_begin();
+        d->insert_enum(&e2, i);
 
-        d->print(*xml);
+        d->print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4EnumDefs_3.xml");
         DBG(cerr << "test_print_insert_enum: doc: " << doc << endl);
@@ -136,12 +140,12 @@ public:
     }
 
     void test_print_assignment() {
-        d->add_enum("first", dods_byte_c, e);
-        d->add_enum("second", dods_int32_c, e2);
+        d->add_enum(&e);
+        d->add_enum(&e2);
 
         D4EnumDefs lhs = *d;
 
-        lhs.print(*xml);
+        lhs.print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4EnumDefs_2.xml");
         DBG(cerr << "test_print_assignment: doc: " << doc << endl);
@@ -150,12 +154,12 @@ public:
     }
 
     void test_print_copy_ctor() {
-        d->add_enum("first", dods_byte_c, e);
-        d->add_enum("second", dods_int32_c, e2);
+        d->add_enum(&e);
+        d->add_enum(&e2);
 
         D4EnumDefs lhs(*d);
 
-        lhs.print(*xml);
+        lhs.print_dap4(*xml);
         string doc = xml->get_doc();
         string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4EnumDefs_2.xml");
         DBG(cerr << "test_print_copy_ctor: doc: " << doc << endl);
diff --git a/unit-tests/D4EnumTest.cc b/unit-tests/D4EnumTest.cc
new file mode 100644
index 0000000..dd33804
--- /dev/null
+++ b/unit-tests/D4EnumTest.cc
@@ -0,0 +1,251 @@
+// -*- 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>
+
+//#define DODS_DEBUG
+
+#include "D4Enum.h"
+#include "D4EnumDefs.h"
+#include "XMLWriter.h"
+#include "debug.h"
+#include "GetOpt.h"
+
+#include "testFile.h"
+#include "test_config.h"
+
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+namespace libdap {
+class D4EnumTest: public TestFixture {
+private:
+    XMLWriter *xml;
+    D4Enum *d;
+
+public:
+    D4EnumTest() : xml(0), d(0) {
+    }
+
+    ~D4EnumTest() {
+    }
+
+    void setUp() {
+        d = new D4Enum("test", "Byte");
+        xml = new XMLWriter;
+    }
+
+    void tearDown() {
+        delete xml;
+        delete d;
+    }
+
+    void test_first_ctor() {
+    	D4Enum e("first", "Byte");
+    	CPPUNIT_ASSERT(e.d_element_type == dods_byte_c);
+    	CPPUNIT_ASSERT(e.name() == "first");
+    }
+
+    // Tests bogus type name
+    void test_first_ctor2() {
+    	D4Enum e("bogus", "String");
+    	CPPUNIT_ASSERT(e.d_element_type == dods_uint64_c);
+    	CPPUNIT_ASSERT(e.name() == "bogus");
+    }
+
+    void test_second_ctor() {
+    	D4Enum e("second", dods_byte_c);
+    	CPPUNIT_ASSERT(e.d_element_type == dods_byte_c);
+    	CPPUNIT_ASSERT(e.name() == "second");
+    }
+
+    // Tests bogus type name
+    void test_second_ctor2() {
+    	D4Enum e("bogus", dods_str_c);
+    	CPPUNIT_ASSERT(e.d_element_type == dods_uint64_c);
+    	CPPUNIT_ASSERT(e.name() == "bogus");
+    }
+
+    void test_set_value() {
+    	D4Enum e("second", dods_byte_c);
+    	dods_byte db = 200;
+    	e.set_value(db);
+    	CPPUNIT_ASSERT(e.d_buf.ui8 == 200);
+    }
+
+    void test_set_value2() {
+    	D4Enum e("second", dods_byte_c);
+    	e.set_value(200);
+    	CPPUNIT_ASSERT(e.d_buf.ui8 == 200);
+    }
+
+    void test_set_value3() {
+    	D4Enum e("third", dods_int32_c);
+    	e.set_value(-65535);
+    	CPPUNIT_ASSERT(e.d_buf.i32 == -65535);
+    }
+
+    void test_value() {
+    	D4Enum e("second", dods_byte_c);
+    	e.set_value(200);
+    	dods_byte db;
+    	e.value(&db);
+    	CPPUNIT_ASSERT(db == 200);
+    }
+
+    void test_value2() {
+    	D4Enum e("third", dods_int32_c);
+    	e.set_value(-65535);
+    	int32_t db;
+    	e.value(&db);
+    	CPPUNIT_ASSERT(db == -65535);
+    }
+
+    void test_copy_ctor() {
+    	D4Enum e("second", dods_byte_c);
+    	e.set_value(200);
+
+    	D4Enum f(e);
+    	CPPUNIT_ASSERT(f.d_element_type == dods_byte_c);
+    	CPPUNIT_ASSERT(f.name() == "second");
+    	CPPUNIT_ASSERT(f.d_buf.ui8 == 200);
+    }
+
+    void test_assignment() {
+    	D4Enum e("second", dods_byte_c);
+    	e.set_value(200);
+
+    	D4Enum f = e;
+    	CPPUNIT_ASSERT(f.d_element_type == dods_byte_c);
+    	CPPUNIT_ASSERT(f.name() == "second");
+    	CPPUNIT_ASSERT(f.d_buf.ui8 == 200);
+    }
+
+    void test_print() {
+    	D4Enum e("test", dods_byte_c);
+        D4EnumDef enum_def("Colors", dods_byte_c);
+
+        e.set_enumeration(&enum_def);
+    	e.set_value((dods_byte)200);
+
+    	XMLWriter xml;
+
+        e.print_dap4(xml);
+        string doc = xml.get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Enum_1.xml");
+        DBG(cerr << "test_print: doc: " << doc << endl);
+        DBG(cerr << "test_print: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_val() {
+    	D4Enum e("test", dods_byte_c);
+        D4EnumDef enum_def("Colors", dods_byte_c);
+
+        e.set_enumeration(&enum_def);
+    	e.set_value(200);
+
+    	ostringstream oss;
+
+        e.print_val(oss, "", true);
+        string doc = oss.str();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Enum_2.txt");
+        DBG(cerr << "test_print: doc: " << doc << endl);
+        DBG(cerr << "test_print: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    CPPUNIT_TEST_SUITE( D4EnumTest );
+
+        CPPUNIT_TEST(test_first_ctor);
+#ifdef NDEBUG
+        CPPUNIT_TEST(test_first_ctor2);
+#endif
+        CPPUNIT_TEST(test_second_ctor);
+#ifdef NDEBUG
+        CPPUNIT_TEST(test_second_ctor2);
+#endif
+
+        CPPUNIT_TEST(test_set_value);
+        CPPUNIT_TEST(test_set_value2);
+        CPPUNIT_TEST(test_set_value3);
+
+        CPPUNIT_TEST(test_value);
+        CPPUNIT_TEST(test_value2);
+
+        CPPUNIT_TEST(test_copy_ctor);
+        CPPUNIT_TEST(test_assignment);
+
+        CPPUNIT_TEST(test_print);
+        CPPUNIT_TEST(test_print_val);
+
+        CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(D4EnumTest);
+
+}
+
+int main(int argc, char*argv[]) {
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = 1;  // debug is a static global
+            break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::D4EnumTest::") + argv[i++];
+
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/D4GroupTest.cc b/unit-tests/D4GroupTest.cc
new file mode 100644
index 0000000..f345652
--- /dev/null
+++ b/unit-tests/D4GroupTest.cc
@@ -0,0 +1,382 @@
+// -*- 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>
+
+//#define DODS_DEBUG 1
+
+#include "D4Group.h"
+#include "D4Attributes.h"
+
+#include "Byte.h"
+#include "Int64.h"
+#include "Structure.h"
+
+#include "XMLWriter.h"
+#include "debug.h"
+
+#include "testFile.h"
+#include "test_config.h"
+#include "GetOpt.h"
+
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+class D4GroupTest: public TestFixture {
+private:
+    XMLWriter *xml;
+    D4Group *root, *named;
+
+public:
+    D4GroupTest() : xml(0), root(0), named(0) {
+    }
+
+    ~D4GroupTest() {
+    }
+
+    void setUp() {
+        root = new D4Group("/");
+        named = new D4Group("test");
+        xml = new XMLWriter;
+    }
+
+    void tearDown() {
+        delete xml;
+        delete root;
+        delete named;
+    }
+
+    void load_group_with_scalars(D4Group *g) {
+        g->add_var_nocopy(new Byte("b"));
+        g->add_var_nocopy(new Int64("i64"));
+    }
+
+    void load_group_with_constructors_and_scalars(D4Group *g) {
+    	Structure *s = new Structure("s");
+    	s->add_var_nocopy(new Byte("b"));
+    	s->add_var_nocopy(new Int64("i64"));
+    	g->add_var_nocopy(s);
+    }
+
+    void load_group_with_nested_constructors_and_scalars(D4Group *g) {
+    	Structure *c = new Structure("c");
+    	c->add_var_nocopy(new Byte("b"));
+    	c->add_var_nocopy(new Int64("i64"));
+
+    	Structure *p = new Structure("p");
+    	p->add_var_nocopy(c);
+
+    	g->add_var_nocopy(p);
+    }
+
+    void load_group_with_stuff(D4Group *g) {
+        g->dims()->add_dim_nocopy(new D4Dimension("lat", 1024));
+        g->dims()->add_dim_nocopy(new D4Dimension("lon", 1024));
+        g->dims()->add_dim_nocopy(new D4Dimension("time", 20));
+
+        D4EnumDef *color_values = new D4EnumDef("colors", dods_byte_c);
+        color_values->add_value("red", 1);
+        color_values->add_value("green", 2);
+        color_values->add_value("blue", 3);
+        g->enum_defs()->add_enum_nocopy(color_values);
+
+        D4Attribute *attr = new D4Attribute("test", StringToD4AttributeType("Int16"));
+        attr->add_value("1");
+        g->attributes()->add_attribute_nocopy(attr);
+    }
+
+    // An empty D4Group object prints nothing; the XMLWriter class adds
+    // a xml doc preface.
+    void test_print_empty() {
+        root->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Group_empty.xml");
+        DBG(cerr << "test_print_empty: doc: " << doc << endl);
+        DBG(cerr << "test_print_empty: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_named_empty() {
+        named->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Group_named_empty.xml");
+        DBG(cerr << "test_print_named_empty: doc: " << doc << endl);
+        DBG(cerr << "test_print_named_empty: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_with_vars() {
+        load_group_with_scalars(root);
+
+        root->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Group_with_scalars.xml");
+        DBG(cerr << "test_print_with_vars: doc: " << doc << endl);
+        DBG(cerr << "test_print_with_vars: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_named_with_vars() {
+        load_group_with_scalars(named);
+
+        named->print_dap4(*xml);
+
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Group_named_with_scalars.xml");
+        DBG(cerr << "test_print_named_with_vars: doc: " << doc << endl);
+        DBG(cerr << "test_print_named_with_vars: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_with_vars_and_stuff() {
+        load_group_with_scalars(root);
+        load_group_with_stuff(root);
+
+        root->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Group_with_scalars_and_stuff.xml");
+        DBG(cerr << "test_print_with_vars_and_stuff: doc: " << doc << endl);
+        DBG(cerr << "test_print_with_vars_and_stuff: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_named_with_vars_and_stuff() {
+        load_group_with_scalars(named);
+        load_group_with_stuff(named);
+
+        named->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Group_named_with_scalars_and_stuff.xml");
+        DBG(cerr << "test_print_named_with_vars_and_stuff: doc: " << doc << endl);
+        DBG(cerr << "test_print_named_with_vars_and_stuff: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_find_var() {
+        load_group_with_scalars(root);
+        load_group_with_stuff(root);
+
+        D4Group *child = new D4Group("child");
+        load_group_with_scalars(child);
+        load_group_with_stuff(child);
+        root->add_group(child);
+
+        child->dims()->add_dim_nocopy(new D4Dimension("extra", 17));
+
+        // Used add_group() and not add_group_nocopy()
+        delete child;
+
+        BaseType *btp = root->find_var("/b");
+        DBG(cerr << "btp: " << btp << ", name:" << btp->name() << endl);
+        DBG(cerr << "btp->parent: " << btp->get_parent() << ", name:" << btp->get_parent()->name() << endl);
+        CPPUNIT_ASSERT(btp && btp->name() == "b");
+        CPPUNIT_ASSERT(btp->get_parent()->name() == "/");
+
+        btp = root->find_var("/child/b");
+        DBG(cerr << "btp: " << btp << ", name:" << btp->name() << endl);
+        DBG(cerr << "btp->parent: " << btp->get_parent() << ", name:" << btp->get_parent()->name() << endl);
+        CPPUNIT_ASSERT(btp && btp->name() == "b");
+        CPPUNIT_ASSERT(btp->get_parent()->name() == "child" && btp->get_parent()->get_parent()->name() == "/");
+    }
+
+    void test_print_everything() {
+        load_group_with_scalars(root);
+        load_group_with_stuff(root);
+
+        D4Group *child = new D4Group("child");
+        load_group_with_scalars(child);
+        load_group_with_stuff(child);
+        root->add_group(child);
+
+        child->dims()->add_dim_nocopy(new D4Dimension("extra", 17));
+
+        // Used add_group() and not add_group_nocopy()
+        delete child;
+
+        root->print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Group_everything.xml");
+        DBG(cerr << "test_print_with_vars_and_stuff: doc: " << doc << endl);
+        DBG(cerr << "test_print_with_vars_and_stuff: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_copy_ctor() {
+        load_group_with_scalars(root);
+        load_group_with_stuff(root);
+
+        D4Group *child = new D4Group("child");
+        load_group_with_scalars(child);
+        load_group_with_stuff(child);
+        root->add_group_nocopy(child); // add it using ...nocopy() this time
+
+        D4Group lhs(*root);
+
+        lhs.print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Group_everything.xml");
+        DBG(cerr << "test_print_copy_ctor: doc: " << doc << endl);
+        DBG(cerr << "test_print_copy_ctor: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_print_assignment() {
+        load_group_with_scalars(root);
+        load_group_with_stuff(root);
+
+        D4Group *child = new D4Group("child");
+        load_group_with_scalars(child);
+        load_group_with_stuff(child);
+        root->add_group_nocopy(child);
+
+        D4Group lhs = *root;
+
+        lhs.print_dap4(*xml);
+        string doc = xml->get_doc();
+        string baseline = readTestBaseline(string(TEST_SRC_DIR) + "/D4-xml/D4Group_everything.xml");
+        DBG(cerr << "test_print_assignment: doc: " << doc << endl);
+        DBG(cerr << "test_print_assignment: baseline: " << baseline << endl);
+        CPPUNIT_ASSERT(doc == baseline);
+    }
+
+    void test_fqn_1() {
+        load_group_with_scalars(root);
+
+        BaseType *btp = root->find_var("b");
+        DBG(cerr << "test_fqn_1: " << btp->FQN() << endl);
+        CPPUNIT_ASSERT(btp->FQN() == "/b");
+    }
+
+    void test_fqn_2() {
+        load_group_with_constructors_and_scalars(root);
+
+        BaseType *btp = root->find_var("s.b");
+        DBG(cerr << "test_fqn_2: " << btp->FQN() << endl);
+        CPPUNIT_ASSERT(btp->FQN() == "/s.b");
+
+        btp = root->find_var("/s.b");
+		DBG(cerr << "test_fqn_2: " << btp->FQN() << endl);
+		CPPUNIT_ASSERT(btp->FQN() == "/s.b");
+    }
+
+    void test_fqn_3() {
+        load_group_with_nested_constructors_and_scalars(root);
+
+        BaseType *btp = root->find_var("p.c.b");
+        DBG(cerr << "test_fqn_3: " << btp->FQN() << endl);
+        CPPUNIT_ASSERT(btp->FQN() == "/p.c.b");
+
+        btp = root->find_var("/p.c.b");
+		DBG(cerr << "test_fqn_3: " << btp->FQN() << endl);
+		CPPUNIT_ASSERT(btp->FQN() == "/p.c.b");
+    }
+
+    void test_fqn_4() {
+    	D4Group *local = new D4Group("child");
+        load_group_with_nested_constructors_and_scalars(local);
+        root->add_group_nocopy(local);
+
+        BaseType *btp = root->find_var("child/p.c.b");
+        DBG(cerr << "test_fqn_4: " << btp->FQN() << endl);
+        CPPUNIT_ASSERT(btp && btp->FQN() == "/child/p.c.b");
+
+        btp = root->find_var("/child/p.c.b");
+		DBG(cerr << "test_fqn_4: " << btp->FQN() << endl);
+		CPPUNIT_ASSERT(btp && btp->FQN() == "/child/p.c.b");
+    }
+
+    CPPUNIT_TEST_SUITE( D4GroupTest );
+
+        CPPUNIT_TEST(test_print_empty);
+
+        CPPUNIT_TEST(test_print_named_empty);
+        CPPUNIT_TEST(test_print_with_vars);
+        CPPUNIT_TEST(test_print_named_with_vars);
+
+        CPPUNIT_TEST(test_print_with_vars_and_stuff);
+
+        CPPUNIT_TEST(test_print_named_with_vars_and_stuff);
+        CPPUNIT_TEST(test_print_everything);
+
+        CPPUNIT_TEST(test_find_var);
+
+        CPPUNIT_TEST(test_print_copy_ctor);
+        CPPUNIT_TEST(test_print_assignment);
+
+        CPPUNIT_TEST(test_fqn_1);
+        CPPUNIT_TEST(test_fqn_2);
+        CPPUNIT_TEST(test_fqn_3);
+        CPPUNIT_TEST(test_fqn_4);
+
+    CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(D4GroupTest);
+
+int
+main(int argc, char *argv[])
+{
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+            case 'd':
+                debug = 1;  // debug is a static global
+                break;
+            default:
+                break;
+        }
+
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("D4GroupTest::") + argv[i++];
+            if (debug)
+                cerr << "Running " << test << endl;
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/DAP4MarshallerTest.cc b/unit-tests/D4MarshallerTest.cc
similarity index 54%
rename from unit-tests/DAP4MarshallerTest.cc
rename to unit-tests/D4MarshallerTest.cc
index 0362d84..509a5f2 100644
--- a/unit-tests/DAP4MarshallerTest.cc
+++ b/unit-tests/D4MarshallerTest.cc
@@ -1,3 +1,30 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
 #include <cppunit/TestFixture.h>
 #include <cppunit/TestAssert.h>
 #include <cppunit/extensions/TestFactoryRegistry.h>
@@ -5,8 +32,6 @@
 #include <cppunit/extensions/HelperMacros.h>
 #include <cppunit/CompilerOutputter.h>
 
-#include "config.h"
-
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -17,19 +42,29 @@
 
 #include <iostream>
 #include <fstream>
+#include <sstream>
 #include <iomanip>
 #include <cstring>
 
-#include "DAP4StreamMarshaller.h"
+#include "D4StreamMarshaller.h"
 
+#include "GetOpt.h"
 #include "debug.h"
+#include "test_config.h"
+
+static bool debug = false;
+static bool write_baselines = false;
+const string path = (string)TEST_SRC_DIR + "/D4-marshaller";
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
 
 using namespace std;
 using namespace libdap;
 
-class DAP4MarshallerTest: public CppUnit::TestFixture {
+class D4MarshallerTest: public CppUnit::TestFixture {
 
-    CPPUNIT_TEST_SUITE( DAP4MarshallerTest );
+    CPPUNIT_TEST_SUITE( D4MarshallerTest );
 
     CPPUNIT_TEST(test_cmp);
     CPPUNIT_TEST(test_scalars);
@@ -37,7 +72,6 @@ class DAP4MarshallerTest: public CppUnit::TestFixture {
     CPPUNIT_TEST(test_str);
     CPPUNIT_TEST(test_opaque);
     CPPUNIT_TEST(test_vector);
-    CPPUNIT_TEST(test_varying_vector);
 
     CPPUNIT_TEST_SUITE_END( );
 
@@ -47,24 +81,23 @@ class DAP4MarshallerTest: public CppUnit::TestFixture {
     bool cmp(const char *buf, unsigned int len, string file) {
         fstream in;
         in.open(file.c_str(), fstream::binary | fstream::in);
-        if (!in) {
-            cerr << "Could not open file: " << file << endl;
-            return false;
-        }
+        if (!in)
+            throw Error("Could not open file: " + file);
 
         vector<char> fbuf(len);
         in.read(&fbuf[0], len);
         if (!in) {
-            cerr << "Could not read " << len << " bytes from file." << endl;
-            return false;
+            ostringstream oss("Could not read ");
+            oss << len << " bytes from file.";
+            throw Error(oss.str());
         }
 
         for (unsigned int i = 0; i < len; ++i)
-            if (*buf++ != fbuf[i]) {
-                cerr << "Response differs from baseline at byte " << i << endl;
-                cerr << "Expected: " << setfill('0') << setw(2) << hex
+            if (buf[i] != fbuf[i]) {
+                DBG(cerr << "Response differs from baseline at byte " << i << endl);
+                DBG(cerr << "Expected: " << setfill('0') << setw(2) << hex
                         << (unsigned int)fbuf[i] << "; got: "
-                        << (unsigned int)buf[i] << dec << endl;
+                        << (unsigned int)buf[i] << dec << endl);
                 return false;
             }
 
@@ -74,16 +107,13 @@ class DAP4MarshallerTest: public CppUnit::TestFixture {
     void write_binary_file(const char *buf, int len, string file) {
         fstream out;
         out.open(file.c_str(), fstream::binary | fstream::out);
-        if (!out) {
-            cerr << "Could not open file: " << file << endl;
-            return;
-        }
-
+        if (!out)
+            throw Error("Could not open file: " + file);
         out.write(buf, len);
     }
 
 public:
-    DAP4MarshallerTest() {
+    D4MarshallerTest() {
     }
 
     void setUp() {
@@ -94,47 +124,54 @@ public:
 
     void test_cmp() {
         char buf[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
-        CPPUNIT_ASSERT(cmp(buf, 16, "test_cmp.dat"));
+        CPPUNIT_ASSERT(cmp(buf, 16, path + "/test_cmp.dat"));
     }
 
     void test_scalars() {
         ostringstream oss;
         // computes checksums and writes data
         try {
-        DAP4StreamMarshaller dsm(oss);
+        D4StreamMarshaller dsm(oss);
 
         dsm.reset_checksum();
 
         dsm.put_byte(17);
         dsm.put_checksum();
+        DBG(cerr << "test_scalars: checksum: " << dsm.get_checksum() << endl);
         dsm.reset_checksum();
 
         dsm.put_int16(17);
         dsm.put_checksum();
+        DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
         dsm.reset_checksum();
 
         dsm.put_int32(17);
         dsm.put_checksum();
+        DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
         dsm.reset_checksum();
 
         dsm.put_int64(17);
         dsm.put_checksum();
+        DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
         dsm.reset_checksum();
 
         dsm.put_uint16(17);
         dsm.put_checksum();
+        DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
         dsm.reset_checksum();
 
         dsm.put_uint32(17);
         dsm.put_checksum();
+        DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
         dsm.reset_checksum();
 
         dsm.put_uint64(17);
         dsm.put_checksum();
+        DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
         dsm.reset_checksum();
 
-        //write_binary_file(oss.str().data(), oss.str().length(), "test_scalars_1_bin.dat");
-        CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), "test_scalars_1_bin.dat"));
+        if (write_baselines) write_binary_file(oss.str().data(), oss.str().length(), path + "/test_scalars_1_bin.dat");
+        CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), path + "/test_scalars_1_bin.dat"));
         }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
@@ -146,20 +183,22 @@ public:
         ostringstream oss;
         // computes checksums and writes data
         try {
-        DAP4StreamMarshaller dsm(oss);
+        D4StreamMarshaller dsm(oss);
 
         dsm.reset_checksum();
 
         dsm.put_float32(17);
         dsm.put_checksum();
+        DBG(cerr << "test_real_scalars: checksum: " << dsm.get_checksum() << endl);
         dsm.reset_checksum();
 
         dsm.put_float64(17);
         dsm.put_checksum();
+        DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
         dsm.reset_checksum();
 
-        //write_binary_file(oss.str().data(), oss.str().length(), "test_scalars_2_bin.dat");
-        CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), "test_scalars_2_bin.dat"));
+        if (write_baselines) write_binary_file(oss.str().data(), oss.str().length(), path + "/test_scalars_2_bin.dat");
+        CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), path + "/test_scalars_2_bin.dat"));
         }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
@@ -170,22 +209,24 @@ public:
     void test_str() {
         ostringstream oss;
         try {
-            DAP4StreamMarshaller dsm(oss);
+            D4StreamMarshaller dsm(oss);
 
             dsm.reset_checksum();
 
             dsm.put_str("This is a test string with 40 characters");
             dsm.put_checksum();
+            DBG(cerr << "test_str: checksum: " << dsm.get_checksum() << endl);
             dsm.reset_checksum();
 
             // 37 chars --> 0x25 --> 0x25 as a 128-bit varint
             dsm.put_url("http://www.opendap.org/lame/unit/test");
             dsm.put_checksum();
+            DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
             dsm.reset_checksum();
 
             // True these are not really scalars...
-            //write_binary_file(oss.str().data(), oss.str().length(), "test_scalars_3_bin.dat");
-            CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), "test_scalars_3_bin.dat"));
+            if (write_baselines) write_binary_file(oss.str().data(), oss.str().length(), path + "/test_scalars_3_bin.dat");
+            CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), path + "/test_scalars_3_bin.dat"));
        }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
@@ -196,22 +237,20 @@ public:
     void test_opaque() {
         ostringstream oss;
         try {
-            DAP4StreamMarshaller dsm(oss);
+            D4StreamMarshaller dsm(oss);
             vector<unsigned char> buf(32768);
             for (int i = 0; i < 32768; ++i)
                 buf[i] = i % (1 << 7);
 
             dsm.reset_checksum();
 
-            dsm.put_opaque(reinterpret_cast<char*>(&buf[0]), 32768);
+            dsm.put_opaque_dap4(reinterpret_cast<char*>(&buf[0]), 32768);
             dsm.put_checksum();
+            DBG(cerr << "test_opaque: checksum: " << dsm.get_checksum() << endl);
             dsm.reset_checksum();
 
-            dsm.put_opaque(reinterpret_cast<char*>(&buf[0]), 32768);
-            dsm.put_checksum();
-
-            //write_binary_file(oss.str().data(), oss.str().length(), "test_opaque_1_bin.dat");
-            CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), "test_opaque_1_bin.dat"));
+            if (write_baselines) write_binary_file(oss.str().data(), oss.str().length(), path + "/test_opaque_1_bin.dat");
+            CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), path + "/test_opaque_1_bin.dat"));
        }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
@@ -222,7 +261,7 @@ public:
     void test_vector() {
         ostringstream oss;
         try {
-            DAP4StreamMarshaller dsm(oss);
+            D4StreamMarshaller dsm(oss);
             vector<unsigned char> buf1(32768);
             for (int i = 0; i < 32768; ++i)
                 buf1[i] = i % (1 << 7);
@@ -231,36 +270,39 @@ public:
 
             dsm.put_vector(reinterpret_cast<char*>(&buf1[0]), 32768);
             dsm.put_checksum();
+            DBG(cerr << "test_vector: checksum: " << dsm.get_checksum() << endl);
             dsm.reset_checksum();
 
             vector<dods_int32> buf2(32768);
             for (int i = 0; i < 32768; ++i)
                 buf2[i] = i % (1 << 9);
 
-            dsm.put_vector(reinterpret_cast<char*>(&buf2[0]), 32768, sizeof(dods_int32), dods_int32_c);
+            dsm.put_vector(reinterpret_cast<char*>(&buf2[0]), 32768, sizeof(dods_int32));
             dsm.put_checksum();
+            DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
             dsm.reset_checksum();
 
             vector<dods_float64> buf3(32768);
             for (int i = 0; i < 32768; ++i)
                 buf3[i] = i % (1 << 9);
 
-            dsm.put_vector(reinterpret_cast<char*>(&buf3[0]), 32768, sizeof(dods_float64), dods_float64_c);
+            dsm.put_vector_float64(reinterpret_cast<char*>(&buf3[0]), 32768);
             dsm.put_checksum();
+            DBG(cerr << "checksum: " << dsm.get_checksum() << endl);
 
-            //write_binary_file(oss.str().data(), oss.str().length(), "test_vector_1_bin.dat");
-            CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), "test_vector_1_bin.dat"));
+            if (write_baselines) write_binary_file(oss.str().data(), oss.str().length(), path + "/test_vector_1_bin.dat");
+            CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), path + "/test_vector_1_bin.dat"));
        }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
             CPPUNIT_FAIL("Caught an exception.");
         }
     }
-
+#if 0
     void test_varying_vector() {
         ostringstream oss;
         try {
-            DAP4StreamMarshaller dsm(oss);
+            D4StreamMarshaller dsm(oss);
             vector<unsigned char> buf1(32768);
             for (int i = 0; i < 32768; ++i)
                 buf1[i] = i % (1 << 7);
@@ -269,14 +311,16 @@ public:
 
             dsm.put_varying_vector(reinterpret_cast<char*>(&buf1[0]), 32768);
             dsm.put_checksum();
+            DBG(cerr << "test_varying_vector: first checksum: " << dsm.get_checksum() << endl);
             dsm.reset_checksum();
 
             vector<dods_int32> buf2(32768);
             for (int i = 0; i < 32768; ++i)
                 buf2[i] = i % (1 << 9);
 
-            dsm.put_varying_vector(reinterpret_cast<char*>(&buf2[0]), 32768, sizeof(dods_int32), dods_int32_c);
+            dsm.put_varying_vector(reinterpret_cast<char*>(&buf2[0]), 32768, sizeof(dods_int32));
             dsm.put_checksum();
+            DBG(cerr << "second checksum: " << dsm.get_checksum() << endl);
             dsm.reset_checksum();
 
             vector<dods_float64> buf3(32768);
@@ -285,27 +329,55 @@ public:
 
             dsm.put_varying_vector(reinterpret_cast<char*>(&buf3[0]), 32768, sizeof(dods_float64), dods_float64_c);
             dsm.put_checksum();
+            DBG(cerr << "third checksum: " << dsm.get_checksum() << endl);
 
-            //write_binary_file(oss.str().data(), oss.str().length(), "test_vector_2_bin.dat");
-            CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), "test_vector_2_bin.dat"));
+            if (write_baselines) write_binary_file(oss.str().data(), oss.str().length(), path + "/test_vector_2_bin.dat");
+            CPPUNIT_ASSERT(cmp(oss.str().data(), oss.str().length(), path + "/test_vector_2_bin.dat"));
        }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
             CPPUNIT_FAIL("Caught an exception.");
         }
     }
-
+#endif
 };
 
-CPPUNIT_TEST_SUITE_REGISTRATION( DAP4MarshallerTest ) ;
+CPPUNIT_TEST_SUITE_REGISTRATION( D4MarshallerTest ) ;
 
-int main(int, char **)
-{
-    CppUnit::TextUi::TestRunner runner;
-    CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
-    runner.addTest(registry.makeTest());
+int main(int argc, char*argv[]) {
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
     runner.setOutputter(CppUnit::CompilerOutputter::defaultOutputter(&runner.result(), std::cerr));
-    bool wasSuccessful = runner.run("", false);
+
+    GetOpt getopt(argc, argv, "dw");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = true;  // debug is a static global
+            break;
+        case 'w':
+            write_baselines = true;
+            break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("D4MarshallerTest::") + argv[i++];
+
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
     return wasSuccessful ? 0 : 1;
 }
-
diff --git a/unit-tests/D4ParserSax2Test.cc b/unit-tests/D4ParserSax2Test.cc
new file mode 100644
index 0000000..943c748
--- /dev/null
+++ b/unit-tests/D4ParserSax2Test.cc
@@ -0,0 +1,379 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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 <cstring>
+
+#include <iostream>
+#include <fstream>
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "GetOpt.h"
+
+#include "DMR.h"
+#include "D4Group.h"
+#include "XMLWriter.h"
+#include "Array.h"
+
+#include "D4BaseTypeFactory.h"
+#include "D4ParserSax2.h"
+#include "D4Maps.h"
+
+#include "InternalErr.h"
+#include "debug.h"
+
+#include "test_config.h"
+#include "testFile.h"
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+static bool debug = false;
+static bool parser_debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
+class D4ParserSax2Test : public TestFixture {
+private:
+    D4ParserSax2 *parser;
+    DMR *dmr;
+    D4BaseTypeFactory *btf;
+    XMLWriter *xml;
+
+public:
+    D4ParserSax2Test() : parser(0), dmr(0), btf(0), xml(0) {}
+    ~D4ParserSax2Test() {}
+
+    void setUp() {
+        parser = new D4ParserSax2();
+        btf = new D4BaseTypeFactory;
+        dmr = new DMR(btf);
+        xml = new XMLWriter("    ");
+    }
+
+    void tearDown() {
+        delete parser;
+        delete dmr;
+        delete btf;
+        delete xml;
+    }
+
+    void compare_dmr_round_trip(const string &src, const string &bl)
+    {
+        try {
+            string name = string(TEST_SRC_DIR) + src;
+            ifstream ifile(name.c_str(), ifstream::in);
+            if (!ifile)
+                throw InternalErr(__FILE__, __LINE__, "Could not open file: " + src);
+
+            parser->intern(ifile, dmr, parser_debug);
+
+            ifile.close();
+
+            dmr->print_dap4(*xml, false);
+            string doc = xml->get_doc();
+            string baseline = readTestBaseline(string(TEST_SRC_DIR) + bl);
+            DBG(cerr << "DMR: " << doc << endl);
+            CPPUNIT_ASSERT(doc == baseline);
+        }
+        catch (Error &e) {
+            CPPUNIT_FAIL(e.get_error_message().c_str());
+        }
+    }
+
+    void compare_dmr_round_trip_string_version(const string &src, const string &bl)
+    {
+        try {
+            string document = readTestBaseline(string(TEST_SRC_DIR) + src);
+            DBG(cerr << "Parsing: " << document << endl);
+
+            parser->intern(document, dmr, parser_debug);
+
+            dmr->print_dap4(*xml, false);
+            string doc = xml->get_doc();
+            string baseline = readTestBaseline(string(TEST_SRC_DIR) + bl);
+            DBG(cerr << "DMR: " << doc << endl);
+            CPPUNIT_ASSERT(doc == baseline);
+        }
+        catch (Error &e) {
+            CPPUNIT_FAIL(e.get_error_message().c_str());
+        }
+    }
+
+    void test_empty_dmr()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_empty.xml", "/D4-xml/DMR_empty_baseline.xml");
+
+    }
+
+    void test_empty_dmr_string_version()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_empty.xml", "/D4-xml/DMR_empty_baseline.xml");
+    }
+
+    void test_attribute_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_0.xml", "/D4-xml/DMR_0_baseline.xml");
+
+    }
+
+    void test_attribute_def_string_version()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_0.xml", "/D4-xml/DMR_0_baseline.xml");
+    }
+
+    void test_nested_attribute_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_0.1.xml", "/D4-xml/DMR_0.1_baseline.xml");
+    }
+
+    void test_dimension_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_1.xml", "/D4-xml/DMR_1_baseline.xml");
+    }
+
+    void test_enum_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_2.xml", "/D4-xml/DMR_2_baseline.xml");
+    }
+
+    void test_enum_def2()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_2.1.xml", "/D4-xml/DMR_2.1_baseline.xml");
+    }
+
+    void test_simple_var_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_3.xml", "/D4-xml/DMR_3_baseline.xml");
+    }
+
+    void test_simple_var_with_attributes_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_3.1.xml", "/D4-xml/DMR_3.1_baseline.xml");
+    }
+
+    void test_array_var_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_3.2.xml", "/D4-xml/DMR_3.2_baseline.xml");
+    }
+
+    void test_array_var_def2()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_3.3.xml", "/D4-xml/DMR_3.3_baseline.xml");
+    }
+
+    void test_array_var_def3()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_3.4.xml", "/D4-xml/DMR_3.4_baseline.xml");
+    }
+
+    void test_array_var_def4()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_3.5.xml", "/D4-xml/DMR_3.5_baseline.xml");
+    }
+
+    void test_array_var_def4_string_version()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_3.5.xml", "/D4-xml/DMR_3.5_baseline.xml");
+    }
+
+    void test_all_simple_var_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_4.xml", "/D4-xml/DMR_4_baseline.xml");
+    }
+
+    void test_opaque_var_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_4.1.xml", "/D4-xml/DMR_4.1_baseline.xml");
+    }
+
+    void test_structure_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_5.xml", "/D4-xml/DMR_5_baseline.xml");
+    }
+
+    void test_structure_with_attributes_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_5.1.xml", "/D4-xml/DMR_5.1_baseline.xml");
+    }
+
+    void test_structure_with_attributes_def_string_version()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_5.1.xml", "/D4-xml/DMR_5.1_baseline.xml");
+    }
+
+    void test_group_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_6.xml", "/D4-xml/DMR_6_baseline.xml");
+    }
+
+    void test_group_with_attributes_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_6.1.xml", "/D4-xml/DMR_6.1_baseline.xml");
+    }
+
+    void test_group_with_enums_def()
+    {
+        compare_dmr_round_trip("/D4-xml/DMR_6.2.xml", "/D4-xml/DMR_6.2_baseline.xml");
+    }
+
+    void test_group_with_attributes_def_string_version()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_6.1.xml", "/D4-xml/DMR_6.1_baseline.xml");
+    }
+
+    void test_array_1()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_7.xml", "/D4-xml/DMR_7_baseline.xml");
+    }
+
+    void test_array_2()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_7.1.xml", "/D4-xml/DMR_7.1_baseline.xml");
+    }
+
+    void test_array_3()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_7.2.xml", "/D4-xml/DMR_7.2_baseline.xml");
+    }
+
+    void test_array_4()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_7.3.xml", "/D4-xml/DMR_7.3_baseline.xml");
+    }
+
+    void test_array_5()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_7.4.xml", "/D4-xml/DMR_7.4_baseline.xml");
+    }
+
+    void test_array_6()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_7.5.xml", "/D4-xml/DMR_7.5_baseline.xml");
+    }
+
+    void test_map_1()
+    {
+        compare_dmr_round_trip_string_version("/D4-xml/DMR_8.xml", "/D4-xml/DMR_8_baseline.xml");
+
+        // NB: dmr is global
+        Array *b1 = dynamic_cast<Array*>(dmr->root()->var("b1"));
+        CPPUNIT_ASSERT(b1 && b1->name() == "b1");
+        Array *x = dynamic_cast<Array*>(dmr->root()->var("x"));	// this is the map
+        CPPUNIT_ASSERT(x && x->name() == "x");
+
+        D4Maps::D4MapsIter m = b1->maps()->map_begin(); // there's only one map...
+        CPPUNIT_ASSERT((*m)->name() == "/x");
+        CPPUNIT_ASSERT((*m)->array() == x);
+        CPPUNIT_ASSERT((*m)->parent() == b1);
+    }
+
+    CPPUNIT_TEST_SUITE( D4ParserSax2Test );
+
+    CPPUNIT_TEST(test_empty_dmr);
+    CPPUNIT_TEST(test_dimension_def);
+    CPPUNIT_TEST(test_attribute_def);
+    CPPUNIT_TEST(test_nested_attribute_def);
+    CPPUNIT_TEST(test_enum_def);
+    CPPUNIT_TEST(test_enum_def2);
+    CPPUNIT_TEST(test_simple_var_def);
+    CPPUNIT_TEST(test_simple_var_with_attributes_def);
+    CPPUNIT_TEST(test_array_var_def);
+    CPPUNIT_TEST(test_array_var_def2);
+    CPPUNIT_TEST(test_array_var_def3);
+    CPPUNIT_TEST(test_array_var_def4);
+    CPPUNIT_TEST(test_all_simple_var_def);
+    CPPUNIT_TEST(test_opaque_var_def);
+
+    CPPUNIT_TEST(test_structure_def);
+    CPPUNIT_TEST(test_structure_with_attributes_def);
+    CPPUNIT_TEST(test_group_def);
+    CPPUNIT_TEST(test_group_with_attributes_def);
+    CPPUNIT_TEST(test_group_with_enums_def);
+
+    CPPUNIT_TEST(test_empty_dmr_string_version);
+    CPPUNIT_TEST(test_attribute_def_string_version);
+    CPPUNIT_TEST(test_group_with_attributes_def_string_version);
+    CPPUNIT_TEST(test_structure_with_attributes_def_string_version);
+    CPPUNIT_TEST(test_array_var_def4_string_version);
+
+    CPPUNIT_TEST(test_array_1);
+    CPPUNIT_TEST(test_array_2);
+    CPPUNIT_TEST(test_array_3);
+    CPPUNIT_TEST(test_array_4);
+    CPPUNIT_TEST(test_array_5);
+    CPPUNIT_TEST(test_array_6);
+
+    CPPUNIT_TEST(test_map_1);
+
+    CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( D4ParserSax2Test );
+
+int main(int argc, char*argv[]) {
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    GetOpt getopt(argc, argv, "dp");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = 1;  // debug is a static global
+            break;
+        case 'p':
+        	parser_debug = true;
+        	break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("D4ParserSax2Test::") + argv[i++];
+            DBG(cerr << "test: " << test << endl);
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
+    xmlMemoryDump();
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/DAP4UnMarshallerTest.cc b/unit-tests/D4UnMarshallerTest.cc
similarity index 51%
rename from unit-tests/DAP4UnMarshallerTest.cc
rename to unit-tests/D4UnMarshallerTest.cc
index 2df8a5b..5830b91 100644
--- a/unit-tests/DAP4UnMarshallerTest.cc
+++ b/unit-tests/D4UnMarshallerTest.cc
@@ -1,3 +1,30 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
 #include <cppunit/TestFixture.h>
 #include <cppunit/TestAssert.h>
 #include <cppunit/extensions/TestFactoryRegistry.h>
@@ -5,38 +32,43 @@
 #include <cppunit/extensions/HelperMacros.h>
 #include <cppunit/CompilerOutputter.h>
 
-#include "config.h"
-
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #include <fcntl.h>
 #include <stdint.h>
 
-//#define DODS_DEBUG2 1
-
 #include <iostream>
 #include <fstream>
 #include <iomanip>
 #include <cstring>
 
-#include "DAP4StreamUnMarshaller.h"
+#include "D4StreamUnMarshaller.h"
+
+#include "Type.h"
 
+#include "GetOpt.h"
 #include "debug.h"
+#include "test_config.h"
+
+static bool debug = false;
+const string path = (string)TEST_SRC_DIR + "/D4-marshaller";
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
 
 using namespace std;
 using namespace libdap;
 
-class DAP4UnMarshallerTest: public CppUnit::TestFixture {
+class D4UnMarshallerTest: public CppUnit::TestFixture {
 
-    CPPUNIT_TEST_SUITE( DAP4UnMarshallerTest );
+    CPPUNIT_TEST_SUITE( D4UnMarshallerTest );
 
     CPPUNIT_TEST(test_scalars);
     CPPUNIT_TEST(test_real_scalars);
     CPPUNIT_TEST(test_str);
     CPPUNIT_TEST(test_opaque);
     CPPUNIT_TEST(test_vector);
-    CPPUNIT_TEST(test_varying_vector);
 
     CPPUNIT_TEST_SUITE_END( );
 
@@ -60,7 +92,7 @@ class DAP4UnMarshallerTest: public CppUnit::TestFixture {
     }
 
 public:
-    DAP4UnMarshallerTest() {
+    D4UnMarshallerTest() {
     }
 
     void setUp() {
@@ -76,57 +108,59 @@ public:
 
         // computes checksums and writes data
         try {
-            in.open("test_scalars_1_bin.dat", fstream::binary | fstream::in);
-            DAP4StreamUnMarshaller dsm(in, is_host_big_endian());
+	    string file = path + "/test_scalars_1_bin.dat";
+	    DBG(cerr << "file: " << file << endl);
+	    in.open(file.c_str(), fstream::binary | fstream::in);
+            D4StreamUnMarshaller dsm(in, is_host_big_endian());
 
             dods_byte b;
             dsm.get_byte(b);
             CPPUNIT_ASSERT(b == 17);
-            string ck = dsm.get_checksum(dsm.get_checksum());
+            string ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "47ed733b8d10be225eceba344d533586");
+            CPPUNIT_ASSERT(ck == "b8b2cf7f");
 
             dods_int16 i1;
             dsm.get_int16(i1);
             CPPUNIT_ASSERT(i1 == 17);
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "e2b50a7929c9fa04c82d9793b9fb710f");
+            CPPUNIT_ASSERT(ck == "120031ef");
 
             dods_int32 i2;
             dsm.get_int32(i2);
             CPPUNIT_ASSERT(i2 == 17);
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "9ef06d55906276f617c008036beaba81");
+            CPPUNIT_ASSERT(ck == "c9e1efe6");
 
             dods_int64 i3;
             dsm.get_int64(i3);
             CPPUNIT_ASSERT(i3 == 17);
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "843fd2acf107350d495cae589a37913c");
+            CPPUNIT_ASSERT(ck == "d533eedc");
 
             dods_uint16 ui1;
             dsm.get_uint16(ui1);
             CPPUNIT_ASSERT(ui1 == 17);
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "e2b50a7929c9fa04c82d9793b9fb710f");
+            CPPUNIT_ASSERT(ck == "120031ef");
 
             dods_uint32 ui2;
             dsm.get_uint32(ui2);
             CPPUNIT_ASSERT(ui2 == 17);
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "9ef06d55906276f617c008036beaba81");
+            CPPUNIT_ASSERT(ck == "c9e1efe6");
 
             dods_uint64 ui3;
             dsm.get_uint64(ui3);
             CPPUNIT_ASSERT(ui3 == 17);
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "843fd2acf107350d495cae589a37913c");
+            CPPUNIT_ASSERT(ck == "d533eedc");
         }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
@@ -145,22 +179,23 @@ public:
 
         // computes checksums and writes data
         try {
-            in.open("test_scalars_2_bin.dat", fstream::binary | fstream::in);
-            DAP4StreamUnMarshaller dsm(in, is_host_big_endian());
+	    string file = path + "/test_scalars_2_bin.dat";
+            in.open(file.c_str(), fstream::binary | fstream::in);
+            D4StreamUnMarshaller dsm(in, is_host_big_endian());
 
             dods_float32 r1;
             dsm.get_float32(r1);
             CPPUNIT_ASSERT(r1 == 17.0);
-            string ck = dsm.get_checksum(dsm.get_checksum());
+            string ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "104e50b0d8d66fcc1ed3ff3f43b71018");
+            CPPUNIT_ASSERT(ck == "d3c5bc59");
 
             dods_float64 r2;
             dsm.get_float64(r2);
             CPPUNIT_ASSERT(r2 == 17.0);
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "77a53e5b4de7c90741dcbe24b827e866");
+            CPPUNIT_ASSERT(ck == "d5a3994b");
         }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
@@ -178,22 +213,23 @@ public:
 
         // computes checksums and writes data
         try {
-            in.open("test_scalars_3_bin.dat", fstream::binary | fstream::in);
-            DAP4StreamUnMarshaller dsm(in, is_host_big_endian());
+	    string file = path + "/test_scalars_3_bin.dat";
+            in.open(file.c_str(), fstream::binary | fstream::in);
+            D4StreamUnMarshaller dsm(in, is_host_big_endian());
 
             string s;
             dsm.get_str(s);
             CPPUNIT_ASSERT(s == "This is a test string with 40 characters");
-            string ck = dsm.get_checksum(dsm.get_checksum());
+            string ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "263c8416bf984a01145f31b9328e6e8b");
+            CPPUNIT_ASSERT(ck == "af117544");
 
             string u;
             dsm.get_url(u);
             CPPUNIT_ASSERT(u == "http://www.opendap.org/lame/unit/test");
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "e761355247b5b64889492373e1758107");
+            CPPUNIT_ASSERT(ck == "41e10081");
         }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
@@ -211,28 +247,19 @@ public:
 
         // computes checksums and writes data
         try {
-            in.open("test_opaque_1_bin.dat", fstream::binary | fstream::in);
-            DAP4StreamUnMarshaller dsm(in, is_host_big_endian());
-
-            // Test both get_opaque calls; this one that expects the caller
-            // to allocate memory.
-            vector<unsigned char> buf(32768);
-            dsm.get_opaque(reinterpret_cast<char*>(&buf[0]), 32768);
-            for (int i = 0; i < 32768; ++i)
-                CPPUNIT_ASSERT(buf[i] == i % (1 << 7));
-            string ck = dsm.get_checksum(dsm.get_checksum());
-            DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "4188b46ae4fcbaeee1b2cb74850a7c65");
+	    string file = path + "/test_opaque_1_bin.dat";
+            in.open(file.c_str(), fstream::binary | fstream::in);
+            D4StreamUnMarshaller dsm(in, is_host_big_endian());
 
             char *buf2;
-            unsigned int len;
-            dsm.get_opaque(&buf2, len);
+            int64_t len;
+            dsm.get_opaque_dap4(&buf2, len);
             CPPUNIT_ASSERT(len == 32768);
             for (int i = 0; i < 32768; ++i)
                 CPPUNIT_ASSERT(buf2[i] == i % (1 << 7));
-            ck = dsm.get_checksum(dsm.get_checksum());
+            string ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "4188b46ae4fcbaeee1b2cb74850a7c65");
+            CPPUNIT_ASSERT(ck == "199ad7f5");
 
             delete buf2;
         }
@@ -252,35 +279,36 @@ public:
 
         // computes checksums and writes data
         try {
-            in.open("test_vector_1_bin.dat", fstream::binary | fstream::in);
-            DAP4StreamUnMarshaller dsm(in, is_host_big_endian());
+	    string file = path + "/test_vector_1_bin.dat";
+            in.open(file.c_str(), fstream::binary | fstream::in);
+            D4StreamUnMarshaller dsm(in, is_host_big_endian());
 
             vector<unsigned char> buf1(32768);
             dsm.get_vector(reinterpret_cast<char*>(&buf1[0]), 32768);
             for (int i = 0; i < 32768; ++i)
                 CPPUNIT_ASSERT(buf1[i] == i % (1 << 7));
-            string ck = dsm.get_checksum(dsm.get_checksum());
+            string ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "4188b46ae4fcbaeee1b2cb74850a7c65");
+            CPPUNIT_ASSERT(ck == "199ad7f5");
 
             vector<dods_int32> buf2(32768);
-            dsm.get_vector(reinterpret_cast<char*>(&buf2[0]), 32768, sizeof(dods_int32), dods_int32_c);
+            dsm.get_vector(reinterpret_cast<char*>(&buf2[0]), 32768, sizeof(dods_int32));
             for (int i = 0; i < 32768; ++i)
                 CPPUNIT_ASSERT(buf2[i] == i % (1 << 9));
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "bde002389f9caa5c590d315ce1b6e34e");
+            CPPUNIT_ASSERT(ck == "5c1bf29f");
 
             vector<dods_float64> buf3(32768);
-            dsm.get_vector(reinterpret_cast<char*>(&buf3[0]), 32768, sizeof(dods_float64), dods_float64_c);
+            dsm.get_vector_float64(reinterpret_cast<char*>(&buf3[0]), 32768);
             for (int i = 0; i < 32768; ++i) {
                 if (buf3[i] != i % (1 << 9))
                     cerr << "buf3[" << i << "]: " << buf3[i] << endl;
                 CPPUNIT_ASSERT(buf3[i] == i % (1 << 9));
             }
-            ck = dsm.get_checksum(dsm.get_checksum());
+            ck = dsm.get_checksum_str();
             DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "f249b4d23ba0fd2afa290fe374a2556b");
+            CPPUNIT_ASSERT(ck == "aafc2a91");
        }
         catch (Error &e) {
             cerr << "Error: " << e.get_error_message() << endl;
@@ -292,71 +320,41 @@ public:
         }
     }
 
-    void test_varying_vector() {
-        fstream in;
-        in.exceptions(ostream::failbit | ostream::badbit);
+};
 
-        // computes checksums and writes data
-        try {
-            in.open("test_vector_2_bin.dat", fstream::binary | fstream::in);
-            DAP4StreamUnMarshaller dsm(in, is_host_big_endian());
+CPPUNIT_TEST_SUITE_REGISTRATION( D4UnMarshallerTest ) ;
 
-            // Reuse the same pointer for all of the data...
-            char *buf;
-            unsigned int len;
-            dsm.get_varying_vector(&buf, len);
-            CPPUNIT_ASSERT(len == 32768);
-            for (int i = 0; i < 32768; ++i)
-                CPPUNIT_ASSERT(buf[i] == i % (1 << 7));
-            string ck = dsm.get_checksum(dsm.get_checksum());
-            DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "4188b46ae4fcbaeee1b2cb74850a7c65");
-            delete buf;
+int main(int argc, char*argv[]) {
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+    runner.setOutputter(CppUnit::CompilerOutputter::defaultOutputter(&runner.result(), std::cerr));
 
-            dods_int32 *i_buf;
-            dsm.get_varying_vector(reinterpret_cast<char**>(&i_buf), len, sizeof(dods_int32), dods_int32_c);
-            CPPUNIT_ASSERT(len == 32768);
-            for (int i = 0; i < 32768; ++i) {
-                if (i_buf[i] != i % (1 << 9))
-                    cerr << "i_buf[" << i << "]: " << i_buf[i] << endl;
-                CPPUNIT_ASSERT(i_buf[i] == i % (1 << 9));
-            }
-            ck = dsm.get_checksum(dsm.get_checksum());
-            DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "bde002389f9caa5c590d315ce1b6e34e");
-            delete i_buf;
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
 
-            dods_float64 *f_buf;
-            dsm.get_varying_vector(reinterpret_cast<char**>(&f_buf), len, sizeof(dods_float64), dods_float64_c);
-            CPPUNIT_ASSERT(len == 32768);
-            for (int i = 0; i < 32768; ++i)
-                CPPUNIT_ASSERT(f_buf[i] == i % (1 << 9));
-            ck = dsm.get_checksum(dsm.get_checksum());
-            DBG2(cerr << "ck: " << ck << endl);
-            CPPUNIT_ASSERT(ck == "f249b4d23ba0fd2afa290fe374a2556b");
-            delete f_buf;
-        }
-        catch (Error &e) {
-            cerr << "Error: " << e.get_error_message() << endl;
-            CPPUNIT_FAIL("Caught an exception.");
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = true;  // debug is a static global
+            break;
+        default:
+            break;
         }
-        catch (istream::failure &e) {
-            cerr << "File error: " << e.what() << endl;
-            CPPUNIT_FAIL("Caught an exception.");
-        }
-    }
 
-};
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("D4UnMarshallerTest::") + argv[i++];
 
-CPPUNIT_TEST_SUITE_REGISTRATION( DAP4UnMarshallerTest ) ;
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
 
-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/DDSTest.cc b/unit-tests/DDSTest.cc
index eb9680a..61f10c3 100644
--- a/unit-tests/DDSTest.cc
+++ b/unit-tests/DDSTest.cc
@@ -22,17 +22,14 @@
 //
 // 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 <sstream>
 
-#include "config.h"
-
-//#define DODS_DEBUG2
-//#define DODS_DEBUG
-
 #include "Byte.h"
 #include "Int16.h"
 #include "UInt16.h"
@@ -50,12 +47,19 @@
 #include "DDS.h"
 
 #include "GNURegex.h"
+#include "GetOpt.h"
 #include "util.h"
 #include "debug.h"
+#include "GetOpt.h"
 
 #include "testFile.h"
 #include "test_config.h"
 
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) {x;} } while(false)
+
 using namespace CppUnit;
 using namespace std;
 
@@ -90,8 +94,7 @@ public:
 
     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);
+        DBG(cerr << "Match: " << match << " should be: " << s.length() << endl);
         return match == static_cast<int> (s.length());
     }
 
@@ -101,15 +104,14 @@ public:
     // 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_1);
         CPPUNIT_TEST(transfer_attributes_test_2);
 
         CPPUNIT_TEST(symbol_name_test);
-#endif
+
         // These test both transfer_attributes() and print_xml()
         CPPUNIT_TEST(print_xml_test);
-#if 1
+
         CPPUNIT_TEST(print_xml_test2);
         CPPUNIT_TEST(print_xml_test3);
 
@@ -128,9 +130,9 @@ public:
         CPPUNIT_TEST(get_response_size_test_c);
         CPPUNIT_TEST(get_response_size_test_c2);
         CPPUNIT_TEST(get_response_size_test_c3);
-        CPPUNIT_TEST(get_response_size_test_seq);
+
+        // see comment in code below. jhrg 2/4/14 CPPUNIT_TEST(get_response_size_test_seq);
         CPPUNIT_TEST(get_response_size_test_seq_c);
-#endif
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -268,7 +270,7 @@ public:
 
         dds2->transfer_attributes(&das);
 
-        DBG(AttrTable &at2 = dds2->var("c%20d")->get_attr_table()); DBG(at2.print(stderr));
+        DBG( dds2->var("c%20d")->get_attr_table().print(stderr) );
 
         ostringstream oss;
         dds2->print_xml_writer(oss, false, "http://localhost/dods/test.xyz");
@@ -292,7 +294,7 @@ public:
             CPPUNIT_FAIL("Error exception");
         }
 
-        DBG(AttrTable &at2 = dds2->var("huh")->get_attr_table()); DBG(at2.print(stderr));
+        DBG(dds2->var("huh")->get_attr_table().print(stderr));
 
         ostringstream oss;
         dds2->print_xml_writer(oss, false, "http://localhost/dods/test.xyz");
@@ -318,7 +320,7 @@ public:
             CPPUNIT_FAIL("Error exception");
         }
 
-        DBG(AttrTable &at2 = dds2->var("huh")->get_attr_table()); DBG(at2.print(stderr));
+        DBG(dds2->var("huh")->get_attr_table().print(stderr));
 
         ostringstream oss;
         dds2->print_xml_writer(oss, false, "http://localhost/dods/test.xyz");
@@ -361,7 +363,7 @@ public:
             CPPUNIT_FAIL("Error exception");
         }
 
-        DBG(AttrTable &at2 = dds2->var("huh")->get_attr_table()); DBG(at2.print(stderr));
+        DBG(dds2->var("huh")->get_attr_table().print(stderr));
 
         ostringstream oss;
         dds2->print_xml_writer(oss, false, "http://localhost/dods/test.xyz");
@@ -443,35 +445,69 @@ public:
         CPPUNIT_ASSERT(dds2->get_request_size(true) == 17288);
     }
 
+#if 0
+    // This test includes a DAP String and the current implementation of Str::width(bool)
+    // returns sizeof(std::string) which I'm not sure is what it should be doing. Return to
+    // this and decide if it should be returning *string or ...? jhrg 2/4/14
+    // FIXME
     void get_response_size_test_seq() {
         ConstraintEvaluator eval;
         dds2->parse((string) TEST_SRC_DIR + "/dds-testsuite/S2000415.HDF.dds");
         eval.parse_constraint("NSCAT%20Rev%2020.NSCAT%20L2", *dds2);
         DBG(cerr << "S2000415.HDF response size: " << dds2->get_request_size(true) << endl);
         DBG(dds2->print_constrained(cerr));
-        CPPUNIT_ASSERT(dds2->get_request_size(true) == 16
-                || dds2->get_request_size(true) == 12);
+        CPPUNIT_ASSERT(dds2->get_request_size(true) == 16 || dds2->get_request_size(true) == 12);
         // sizeof(string) == 8 or 4 depending on the compiler version (?)
     }
+#endif
 
     void get_response_size_test_seq_c() {
         ConstraintEvaluator eval;
         dds2->parse((string) TEST_SRC_DIR + "/dds-testsuite/S2000415.HDF.dds");
         eval.parse_constraint("NSCAT%20Rev%2020.NSCAT%20L2.Low_Wind_Speed_Flag", *dds2);
         DBG(cerr << "S2000415.HDF response size: " << dds2->get_request_size(true) << endl);
+        DBG(dds2->print_constrained(cerr));
         CPPUNIT_ASSERT(dds2->get_request_size(true) == 4);
     }
 
 };
+
 CPPUNIT_TEST_SUITE_REGISTRATION(DDSTest);
 
 }
 
-int main(int, char *[]) {
+int main(int argc, char*argv[]) {
     CppUnit::TextTestRunner runner;
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
 
-    bool wasSuccessful = runner.run("", false);
+    GetOpt getopt(argc, argv, "d");
+    int option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = 1;  // debug is a static global
+            break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::DDSTest::") + argv[i++];
+            DBG(cerr << "test: " << test << endl);
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
+    xmlMemoryDump();
 
     return wasSuccessful ? 0 : 1;
 }
diff --git a/unit-tests/DDXParserTest.cc b/unit-tests/DDXParserTest.cc
index deb3b7f..a4bc081 100644
--- a/unit-tests/DDXParserTest.cc
+++ b/unit-tests/DDXParserTest.cc
@@ -1,3 +1,4 @@
+
 // -*- mode: c++; c-basic-offset:4 -*-
 
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
@@ -28,61 +29,50 @@
 #include <cppunit/extensions/TestFactoryRegistry.h>
 #include <cppunit/extensions/HelperMacros.h>
 
-#include <istream>
+#include "GetOpt.h"
 
 #include "DDXParserSAX2.h"
 #include "BaseTypeFactory.h"
 #include "ObjectType.h"
 #include "mime_util.h"
-#include "GetOpt.h"
 #include "debug.h"
 
-#include "test_config.h"
+#include <test_config.h>
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
 
 static bool debug = false;
 
 #undef DBG
 #define DBG(x) do { if (debug) (x); } while(false);
 
-using namespace CppUnit;
-using namespace std;
-using namespace libdap;
-
 namespace libdap {
 
-class DDXParserTest: public TestFixture {
+class DDXParserTest : public TestFixture {
 private:
-	BaseTypeFactory *factory;
-	DDXParser *ddx_parser;
-	DDS *dds;
+    BaseTypeFactory *factory;
+    DDXParser *ddx_parser;
+    DDS *dds;
 
 public:
-	DDXParserTest()
-	{
-	}
-	~DDXParserTest()
-	{
-	}
+    DDXParserTest() {}
+    ~DDXParserTest() {}
 
-	void setUp()
-	{
-		factory = new BaseTypeFactory;
-		ddx_parser = new DDXParser(factory);
-		dds = new DDS(factory);
-	}
+    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;
-	}
+    void tearDown() {
+        delete ddx_parser; ddx_parser = 0;
+        delete factory; factory = 0;
+        delete dds; dds = 0;
+    }
 
-CPPUNIT_TEST_SUITE( DDXParserTest )
-	;
+    CPPUNIT_TEST_SUITE( DDXParserTest );
 
 	CPPUNIT_TEST(other_xml_parse_test1);
 	CPPUNIT_TEST(other_xml_parse_test2);
@@ -106,211 +96,242 @@ CPPUNIT_TEST_SUITE( DDXParserTest )
 	// FILE I/O tests
 	CPPUNIT_TEST(top_level_simple_types_test_file_stream);
 	CPPUNIT_TEST(structure_test_file_ptr);
+
+#if 0
+	// All of these fail; maybe because on OSX 10.9 something about
+	// libxml2 is odd. Investigate. jhrg 2/4/14
+	// FIXME
+
 	// C++ Stream I/O tests
 	CPPUNIT_TEST(top_level_simple_types_test_cpp_stream);
 	CPPUNIT_TEST(structure_test_cpp_stream);
 	CPPUNIT_TEST(sequence_test_cpp_stream);
 	CPPUNIT_TEST(grid_test_cpp_stream);
-
-	// 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.");
-		}
-	}
-
+#endif
+    // 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.");
+        }
+    }
+
+#if 0 // working
+    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.");
+        }
+    }
+#else
 	void top_level_simple_types_test_file_stream()
 	{
 		FILE *in;
@@ -340,8 +361,8 @@ CPPUNIT_TEST_SUITE( DDXParserTest )
 			string blob;
 			ifstream in(((string) TEST_SRC_DIR + "/ddx-testsuite/test.04.ddx").c_str());
 			ddx_parser->intern_stream(in, dds, blob);
-			CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
 			DBG(dds->print_xml(cout, false));
+			CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
 		}
 		catch (DDXParseFailed &e) {
 			DBG(cerr << endl << "DDXParseFailed: " << e.get_error_message() << endl);
@@ -366,138 +387,151 @@ CPPUNIT_TEST_SUITE( DDXParserTest )
 			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 structure_test_file_ptr()
-	{
-		FILE *in;
-		try {
-			string blob;
-			in = fopen((string(TEST_SRC_DIR) + "/ddx-testsuite/test.09.ddx").c_str(), "r");
-			ddx_parser->intern_stream(in, dds, blob);
-			fclose(in);
-			CPPUNIT_ASSERT(dds->get_dataset_name() == "testdata");
-			DBG(dds->print_xml(cout, false));
-		}
-		catch (DDXParseFailed &e) {
-			fclose(in);
-			DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
-			CPPUNIT_FAIL("test.09.ddx failed.");
-		}
-	}
-
-	void structure_test_cpp_stream()
-	{
-		try {
-			string blob;
-			ifstream input((string(TEST_SRC_DIR) + "/ddx-testsuite/test.09.ddx").c_str());
-			ddx_parser->intern_stream(input, 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 sequence_test_cpp_stream()
-	{
-		try {
-			string blob;
-			ifstream input((string(TEST_SRC_DIR) + "/ddx-testsuite/test.0a.ddx").c_str());
-			ddx_parser->intern_stream(input, 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.");
-		}
-	}
+#endif
+
+    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 structure_test_file_ptr()
+    {
+	FILE *in;
+	try {
+	    string blob;
+	    in = fopen((string(TEST_SRC_DIR) + "/ddx-testsuite/test.09.ddx").c_str(), "r");
+	    ddx_parser->intern_stream(in, dds, blob);
+	    fclose(in);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "testdata");
+	    DBG(dds->print_xml(cout, false));
+	}
+	catch (DDXParseFailed &e) {
+	    fclose(in);
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.09.ddx failed.");
+	}
+    }
+
+    void structure_test_cpp_stream()
+    {
+	try {
+	    string blob;
+	    ifstream input((string(TEST_SRC_DIR) + "/ddx-testsuite/test.09.ddx").c_str());
+	    ddx_parser->intern_stream(input, 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_cpp_stream()
+    {
+	try {
+	    string blob;
+	    ifstream input((string(TEST_SRC_DIR) + "/ddx-testsuite/test.0a.ddx").c_str());
+	    ddx_parser->intern_stream(input, 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 grid_test_cpp_stream()
 	{
@@ -514,165 +548,183 @@ CPPUNIT_TEST_SUITE( DDXParserTest )
 		}
 	}
 
-	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());
-		}
-	}
+    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", dods_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 argc, char*argv[])
-{
-	CppUnit::TextTestRunner runner;
-	runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
-
-	GetOpt getopt(argc, argv, "d");
-	char option_char;
-	while ((option_char = getopt()) != EOF)
-		switch (option_char) {
-		case 'd':
-			debug = 1;  // debug is a static global
-			break;
-		default:
-			break;
-		}
-
-	bool wasSuccessful = true;
-	string test = "";
-	int i = getopt.optind;
-	if (i == argc) {
-		// run them all
-		wasSuccessful = runner.run("");
-	}
-	else {
-		while (i < argc) {
-			test = string("libdap::DDXParserTest::") + argv[i++];
-
-			wasSuccessful = wasSuccessful && runner.run(test);
-		}
-	}
-
-	return wasSuccessful ? 0 : 1;
+CPPUNIT_TEST_SUITE_REGISTRATION( DDXParserTest );
+
+int main(int argc, char*argv[]) {
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    GetOpt getopt(argc, argv, "d");
+    int option_char;
+    while ((option_char = getopt()) != EOF)
+	switch (option_char) {
+	  case 'd':
+	    debug = 1;  // debug is a static global
+	    break;
+	  default:
+	    break;
+	}
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::DDXParserTest::") + argv[i++];
+            DBG(cerr << "test: " << test << endl);
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
+    xmlMemoryDump();
+
+    return wasSuccessful ? 0 : 1;
 }
diff --git a/unit-tests/DMRTest.cc b/unit-tests/DMRTest.cc
new file mode 100644
index 0000000..74108d0
--- /dev/null
+++ b/unit-tests/DMRTest.cc
@@ -0,0 +1,326 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2014 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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 <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 "DMR.h"
+#include "XMLWriter.h"
+#include "D4BaseTypeFactory.h"
+#include "D4ParserSax2.h"
+
+#include "GNURegex.h"
+#include "GetOpt.h"
+#include "util.h"
+#include "debug.h"
+#include "GetOpt.h"
+
+#include "testFile.h"
+#include "test_config.h"
+
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) {x;} } while(false)
+
+using namespace CppUnit;
+using namespace std;
+
+namespace libdap {
+
+class DMRTest: public TestFixture {
+private:
+
+public:
+    DMRTest() {
+    }
+    ~DMRTest() {
+    }
+
+    void setUp() {
+    }
+
+    void tearDown() {
+    }
+
+    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());
+    }
+
+    /**
+     * Given the name of a DDS and optional DAS file, build a DMR using the
+     * hackery known as transform_to_dap4 and the new DMR ctor.
+     *
+     * @param dds_file
+     * @param attr
+     * @return A pointer to the new DMR; caller must delete
+     */
+    DMR *build_dmr(const string &dds_file, const string &attr = "") {
+		try {
+			string prefix = string(TEST_SRC_DIR) + "/dds-testsuite/";
+
+			BaseTypeFactory factory;
+			DDS dds(&factory, dds_file);
+			dds.parse(prefix + dds_file);
+			DBG(cerr << "DDS: " << endl; dds.print(cerr));
+
+			if (!attr.empty()) {
+				DAS das;
+				das.parse(prefix + attr);
+				dds.transfer_attributes(&das);
+			}
+
+			D4BaseTypeFactory d4_factory;
+			return new DMR(&d4_factory, dds);
+		}
+    	catch (Error &e) {
+    		CPPUNIT_FAIL(string("Caught Error: ") + e.get_error_message());
+    	}
+
+    	return 0;
+    }
+
+    void test_template(const string &dds_file, const string &dmr_baseline, const string &attr = "") {
+    	DMR *dmr = 0;
+		try {
+			dmr = build_dmr(dds_file, attr);
+			XMLWriter xml;
+			dmr->print_dap4(xml);
+			DBG(cerr << "DMR: " << endl << xml.get_doc() << endl);
+
+			string prefix = string(TEST_SRC_DIR) + "/dds-testsuite/";
+			CPPUNIT_ASSERT(string(xml.get_doc()) == readTestBaseline(prefix + dmr_baseline));
+			delete dmr;
+		}
+    	catch (Error &e) {
+    		delete dmr;
+    		CPPUNIT_FAIL(string("Caught Error: ") + e.get_error_message());
+    	}
+    }
+
+    CPPUNIT_TEST_SUITE( DMRTest );
+
+    CPPUNIT_TEST(test_dmr_from_dds_1);
+    CPPUNIT_TEST(test_dmr_from_dds_2);
+    CPPUNIT_TEST(test_dmr_from_dds_3);
+    CPPUNIT_TEST(test_dmr_from_dds_4);
+    CPPUNIT_TEST(test_dmr_from_dds_5);
+
+    CPPUNIT_TEST(test_dmr_from_dds_with_attr_1);
+    CPPUNIT_TEST(test_dmr_from_dds_with_attr_2);
+
+    CPPUNIT_TEST(test_copy_ctor);
+    CPPUNIT_TEST(test_copy_ctor_2);
+    CPPUNIT_TEST(test_copy_ctor_3);
+    CPPUNIT_TEST(test_copy_ctor_4);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    // Test a DDS with simple scalar types and no attributes
+    void test_dmr_from_dds_1() {
+    	test_template("test.1", "test.1.dmr");
+    }
+
+    // What about arrays? This should build shared dimensions
+    void test_dmr_from_dds_2() {
+    	test_template("fnoc1.nc.dds", "fnoc1.nc.dmr");
+    }
+
+    void test_dmr_from_dds_3() {
+    	test_template("3B42.980909.5.HDF.dds", "3B42.980909.5.HDF.dmr");
+    }
+
+    void test_dmr_from_dds_4() {
+    	test_template("S2000415.HDF.dds", "S2000415.HDF.dmr");
+    }
+
+    void test_dmr_from_dds_5() {
+    	test_template("coads_climatology.nc.dds", "coads_climatology.nc.dmr");
+    }
+
+    void test_dmr_from_dds_with_attr_1() {
+    	test_template("test.1", "test.1.attr.dmr", "test.1.das");
+    }
+
+    void  test_dmr_from_dds_with_attr_2() {
+    	// The 'hacked' file has global attributes
+    	test_template("3B42.980909.5.HDF.dds", "3B42.980909.5.hacked.2.HDF.attr.dmr", "3B42.980909.5.hacked.2.HDF.das");
+    }
+
+    void test_copy_ctor() {
+    	DMR *dmr = build_dmr("test.1", "test.1.das");
+    	DMR *dmr_2 = new DMR(*dmr);
+
+		XMLWriter xml;
+		dmr->print_dap4(xml);
+		string dmr_src = string(xml.get_doc());
+		DBG(cerr << "DMR SRC: " << endl << dmr_src << endl);
+
+		XMLWriter xml2;
+		dmr_2->print_dap4(xml2);
+		string dmr_dest = string(xml2.get_doc());
+		DBG(cerr << "DMR DEST: " << endl << dmr_dest << endl);
+
+		delete dmr;
+		delete dmr_2;
+		CPPUNIT_ASSERT(dmr_src == dmr_dest);
+
+    }
+
+    // This tests if using the copy still works after the original is deleted
+    void test_copy_ctor_2() {
+    	DMR *dmr = build_dmr("test.1", "test.1.das");
+    	DMR *dmr_2 = new DMR(*dmr);
+
+		XMLWriter xml;
+		dmr->print_dap4(xml);
+		string dmr_src = string(xml.get_doc());
+		DBG(cerr << "DMR SRC: " << endl << dmr_src << endl);
+
+		delete dmr;
+
+		XMLWriter xml2;
+		dmr_2->print_dap4(xml2);
+		string dmr_dest = string(xml2.get_doc());
+		DBG(cerr << "DMR DEST: " << endl << dmr_dest << endl);
+
+		delete dmr_2;
+		CPPUNIT_ASSERT(dmr_src == dmr_dest);
+
+    }
+
+    // Test the grid/coverage and copy ctor code
+    void test_copy_ctor_3() {
+    	DMR *dmr = build_dmr("coads_climatology.nc.dds", "coads_climatology.nc.das");
+    	DMR *dmr_2 = new DMR(*dmr);
+
+		XMLWriter xml;
+		dmr->print_dap4(xml);
+		string dmr_src = string(xml.get_doc());
+		DBG(cerr << "DMR SRC: " << endl << dmr_src << endl);
+
+		XMLWriter xml2;
+		dmr_2->print_dap4(xml2);
+		string dmr_dest = string(xml2.get_doc());
+		DBG(cerr << "DMR DEST: " << endl << dmr_dest << endl);
+
+		delete dmr;
+		delete dmr_2;
+		CPPUNIT_ASSERT(dmr_src == dmr_dest);
+
+    }
+
+    // Make the same test as above, but bypass the DMR ctor that uses a DDS object.
+    void test_copy_ctor_4() {
+    	D4BaseTypeFactory factory;
+    	DMR *dmr = new DMR(&factory, "coads");
+
+    	string prefix = string(TEST_SRC_DIR) + "/D4-xml/coads_climatology.nc.xml";
+    	ifstream ifs(prefix.c_str());
+    	D4ParserSax2 parser;
+    	parser.intern(ifs, dmr);
+
+    	DMR *dmr_2 = new DMR(*dmr);
+
+		XMLWriter xml;
+		dmr->print_dap4(xml);
+		string dmr_src = string(xml.get_doc());
+		DBG(cerr << "DMR SRC: " << endl << dmr_src << endl);
+
+		XMLWriter xml2;
+		dmr_2->print_dap4(xml2);
+		string dmr_dest = string(xml2.get_doc());
+		DBG(cerr << "DMR DEST: " << endl << dmr_dest << endl);
+
+		delete dmr;
+		delete dmr_2;
+		CPPUNIT_ASSERT(dmr_src == dmr_dest);
+
+    }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DMRTest);
+
+
+} // namepsace libdap
+
+int main(int argc, char*argv[]) {
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = 1;  // debug is a static global
+            break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::DMRTest::") + argv[i++];
+            DBG(cerr << "test: " << test << endl);
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
+    xmlMemoryDump();
+
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/HTTPCacheTest.cc b/unit-tests/HTTPCacheTest.cc
index cff8263..d57f9fb 100644
--- a/unit-tests/HTTPCacheTest.cc
+++ b/unit-tests/HTTPCacheTest.cc
@@ -1,4 +1,3 @@
-
 // -*- mode: c++; c-basic-offset:4 -*-
 
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
@@ -32,6 +31,7 @@
 #include <vector>
 #include <algorithm>
 #include <memory>
+#include <iterator>
 
 #include <cppunit/TextTestRunner.h>
 #include <cppunit/extensions/TestFactoryRegistry.h>
@@ -43,9 +43,10 @@
 #include "SignalHandler.h"	// Needed to clean up this singleton.
 #endif
 #include "RCReader.h"		// ditto
+#include"GetOpt.h"
+
+// #define DODS_DEBUG
 
-//#define DODS_DEBUG 1
-//#define DODS_DEBUG2 2
 #include "debug.h"
 
 #if defined(DODS_DEBUG) || defined(DODS_DEBUG2)
@@ -60,11 +61,14 @@ using namespace std;
 #define W_OK 2
 #endif
 
-namespace libdap
-{
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
+namespace libdap {
 
-inline static int
-file_size(string name)
+inline static int file_size(string name)
 {
     struct stat s;
     stat(name.c_str(), &s);
@@ -85,7 +89,7 @@ print_entry(HTTPCache *, HTTPCacheTable::CacheEntry **e)
 // 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 {
+class HTTPCacheTest: public TestFixture {
 private:
     HTTPCache *hc;
     HTTPConnect *http_conn;
@@ -98,56 +102,63 @@ private:
 protected:
 
 public:
-    HTTPCacheTest() : http_conn(0) {
-	putenv((char*)"DODS_CONF=./cache-testsuite/dodsrc");
-	http_conn = new HTTPConnect(RCReader::instance());
-
-	DBG2(cerr << "Entering 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() :
+            http_conn(0)
+    {
+        putenv((char*) "DODS_CONF=./cache-testsuite/dodsrc");
+        http_conn = new HTTPConnect(RCReader::instance());
+
+        DBG2(cerr << "Entering 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);
+    ~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;
+        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 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);
+    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);
@@ -165,13 +176,11 @@ public:
     CPPUNIT_TEST(calculate_time_test);
     CPPUNIT_TEST(write_metadata_test);
     CPPUNIT_TEST(cache_response_test);
-#endif
 #if 0
     // This test does not seem to work in New Zealand - maybe because
     // of the dateline??? jhrg 1/31/13
     CPPUNIT_TEST(is_url_valid_test);
 #endif
-#if 1
     CPPUNIT_TEST(get_cached_response_test);
 
     CPPUNIT_TEST(perform_garbage_collection_test);
@@ -180,94 +189,91 @@ public:
     CPPUNIT_TEST(get_conditional_response_headers_test);
     CPPUNIT_TEST(update_response_test);
     CPPUNIT_TEST(cache_gc_test);
-#endif
 
-    CPPUNIT_TEST_SUITE_END();
+    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 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());
+    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);
+        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();
-	}
+        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());
+    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");
+        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);
+        char *tmpstr = "\"3f62c-157-139c2680\"";
+        CPPUNIT_ASSERT(e->etag == tmpstr);
 #else
-		CPPUNIT_ASSERT(e->etag == "\"3f62c-157-139c2680\"");
+        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);
+        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();
+        e2->unlock();
 #endif
-		e2->unlock_read_response();
+        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());
+        // 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";
+        // 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);
+        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);
+        // 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();
+        g->unlock();
 #endif
-		g->unlock_read_response();
+        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);
-	}
+        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() {
+    void cache_index_write_test()
+    {
         try {
             HTTPCache * hc_3 = new HTTPCache("cache-testsuite/dods_cache/", true);
             hc_3->d_http_cache_table->add_entry_to_cache_table(
@@ -281,7 +287,7 @@ public:
             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);
-            cerr << "Got locked entry" << endl;
+            DBG(cerr << "Got locked entry" << endl);
             CPPUNIT_ASSERT(e);
             CPPUNIT_ASSERT(e->url == localhost_url);
             e->unlock_read_response();
@@ -292,577 +298,596 @@ public:
             hc_4 = 0;
         }
         catch (Error &e) {
-            cerr << "Fail: " << e.get_error_message() << endl;
-            CPPUNIT_FAIL("Caugt exception.");
+            //cerr << "Fail: " << e.get_error_message() << endl;
+            CPPUNIT_FAIL(e.get_error_message());
         }
     }
 
-	void create_cache_root_test() {
-		hc->create_cache_root("/tmp/silly/");
-		CPPUNIT_ASSERT(access("/tmp/silly/", F_OK) == 0);
-		remove("/tmp/silly");
+    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);
-		}
+        // 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() {
+    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/");
+        // 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/");
-	}
+        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();
+    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);
+        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());
-	}
+        // 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;
+    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);
+        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);
+        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());
+        CPPUNIT_ASSERT(!hc->get_single_user_lock());
 
-		remove("/tmp/dods_test_cache/.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);
+    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) {
-		}
+        // 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);
+        }
+
+#ifdef DODS_DEBUG
+        std::ostream_iterator<string> out_it(std::cerr, "\n");
+        cerr << "Cached headers: ";
+        std::copy(cached_headers.begin(), cached_headers.end(), out_it);
+        cerr << "Headers: ";
+        std::copy(headers->begin(), headers->end(), out_it);
 #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;
+
+        CPPUNIT_ASSERT(i == cached_headers.end());
+        // This may not be true if. For example, keep-alive might appear in the list of headers
+        // received, but not in the list of headers cached.
+        // CPPUNIT_ASSERT(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();
+            e1->unlock();
 #endif
-			e1->unlock_read_response();
+            e1->unlock_read_response();
 #if 0
-			e2->unlock();
+            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;
+            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();
+            e1->unlock();
 #endif
-			e1->unlock_read_response();
+            e1->unlock_read_response();
 #if 0
-			e2->unlock();
+            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();
+            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();
+        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);
-		}
-	}
+    }
+
+    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()
+    {
+        HTTPCache *c = 0;
+        try {
+            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;
+            }
+
+            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;
+            }
+
+            // 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(cerr << endl);
+            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());
+
+            delete c;
+        }
+        catch (Error &e) {
+            delete c;
+            CPPUNIT_FAIL(e.get_error_message());
+        }
+
+        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;
+
+            // The 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);
+        }
+    }
 
 };
 
@@ -870,17 +895,43 @@ 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() );
+int main(int argc, char*argv[])
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+            case 'd':
+                debug = 1;  // debug is a static global
+                break;
+            default:
+                break;
+        }
 
-	bool wasSuccessful = runner.run("", false) ;
+    // Run cleanup here, so that the first run works (since this code now
+    // sets up the tests).
+    // This gives valgrind fits...
+    system("cd cache-testsuite && ./cleanup.sh");
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::HTTPCacheTest::") + argv[i++];
 
-	cerr.flush();
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
 
-	return wasSuccessful ? 0 : 1;
+    return wasSuccessful ? 0 : 1;
 }
+
diff --git a/unit-tests/HTTPConnectTest.cc b/unit-tests/HTTPConnectTest.cc
index 803ea6a..4cd8c5b 100644
--- a/unit-tests/HTTPConnectTest.cc
+++ b/unit-tests/HTTPConnectTest.cc
@@ -4,7 +4,7 @@
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
 // Access Protocol.
 
-// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Copyright (c) 2002,2003,2013 OPeNDAP, Inc.
 // Author: James Gallagher <jgallagher at opendap.org>
 //
 // This library is free software; you can redistribute it and/or
@@ -33,8 +33,6 @@
 #include <algorithm>
 #include <functional>
 
-//#define DODS_DEBUG
-
 #include "GNURegex.h"
 #include "HTTPConnect.h"
 #include "RCReader.h"
@@ -46,6 +44,13 @@
 using namespace CppUnit;
 using namespace std;
 
+#include"GetOpt.h"
+
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
 namespace libdap
 {
 
@@ -57,6 +62,8 @@ class HTTPConnectTest: public TestFixture {
     string lm;
     string netcdf_das_url;
 
+    // char env_data[128];
+
   protected:
     bool re_match(Regex & r, const char *s) {
         return r.match(s, strlen(s)) == (int) strlen(s);
@@ -81,14 +88,13 @@ class HTTPConnectTest: public TestFixture {
             bool operator()(const string &arg) { return arg.find(d_header) == 0; }
     };
 
-  public:
-     HTTPConnectTest() {
-    }
-    ~HTTPConnectTest() {
-    }
+    public:
+    HTTPConnectTest() { }
+    ~HTTPConnectTest() { }
 
     void setUp() {
-        putenv((char*)"DODS_CONF=cache-testsuite/dodsrc");
+        DBG(cerr << "Setting the DODS_CONF env var" << endl);
+        setenv("DODS_CONF", "cache-testsuite/dodsrc", 1);
         http = new HTTPConnect(RCReader::instance());
 
         localhost_url = "http://test.opendap.org/test-304.html";
@@ -97,7 +103,9 @@ class HTTPConnectTest: public TestFixture {
         // 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
+        // On 10/13/14 we moved to a new httpd and the etag value changed.
+        // jhrg 10/14/14
+        etag = "\"2a008e-157-3fbcd139c2680\""; //\"a10df-157-139c2680\""; // a10df-157-139c2680a
         lm = "Wed, 13 Jul 2005 19:32:26 GMT";
 
         localhost_pw_url =
@@ -109,19 +117,34 @@ class HTTPConnectTest: public TestFixture {
     }
 
     void tearDown() {
+        // normal code doesn't do this - it happens at exit() but not doing
+        // this here make valgrind think there are leaks.
+        http->d_http_cache->delete_instance();
         delete http;
         http = 0;
+        unsetenv("DODS_CONF");
     }
 
     CPPUNIT_TEST_SUITE(HTTPConnectTest);
 
     CPPUNIT_TEST(read_url_test);
-    CPPUNIT_TEST(fetch_url_test);
+
+    CPPUNIT_TEST(fetch_url_test_1);
+    CPPUNIT_TEST(fetch_url_test_2);
+    CPPUNIT_TEST(fetch_url_test_3);
+    CPPUNIT_TEST(fetch_url_test_4);
+
+    CPPUNIT_TEST(fetch_url_test_1_cpp);
+    CPPUNIT_TEST(fetch_url_test_2_cpp);
+    CPPUNIT_TEST(fetch_url_test_3_cpp);
+    CPPUNIT_TEST(fetch_url_test_4_cpp);
+
     CPPUNIT_TEST(get_response_headers_test);
     CPPUNIT_TEST(server_version_test);
     CPPUNIT_TEST(type_test);
 
     CPPUNIT_TEST(cache_test);
+    CPPUNIT_TEST(cache_test_cpp);
 
     CPPUNIT_TEST(set_accept_deflate_test);
     CPPUNIT_TEST(set_xdap_protocol_test);
@@ -136,6 +159,8 @@ class HTTPConnectTest: public TestFixture {
         vector < string > *resp_h = new vector < string >;;
 
         try {
+        	DBG(cerr << "Entering read_url_test... " << endl);
+
             FILE *dump = fopen("/dev/null", "w");
             long status = http->read_url(localhost_url, dump, resp_h);
             CPPUNIT_ASSERT(status == 200);
@@ -149,6 +174,7 @@ class HTTPConnectTest: public TestFixture {
             DBG(cerr << "If modified since test, status: " << status << endl);
             DBG(copy(resp_h->begin(), resp_h->end(),
                      ostream_iterator < string > (cerr, "\n")));
+            DBG(cerr << endl);
             CPPUNIT_ASSERT(status == 304);
 
             // Now test an etag
@@ -160,6 +186,7 @@ class HTTPConnectTest: public TestFixture {
             DBG(cerr << "If none match test, status: " << status << endl);
             DBG(copy(resp_h->begin(), resp_h->end(),
                      ostream_iterator < string > (cerr, "\n")));
+            DBG(cerr << endl);
             CPPUNIT_ASSERT(status == 304);
 
             // now test a combined etag and time4
@@ -185,14 +212,12 @@ class HTTPConnectTest: public TestFixture {
         }
     }
 
-    void fetch_url_test() {
-        DBG(cerr << "Entering fetch_url_test" << endl);
+    void fetch_url_test_1() {
+        DBG(cerr << "Entering fetch_url_test 1" << endl);
         HTTPResponse *stuff = 0;
         char c;
         try {
-            DBG(cerr << "    First request..." << endl;)
             stuff = http->fetch_url(localhost_url);
-            DBG(cerr << "    Back from first request." << endl);
             CPPUNIT_ASSERT(fread(&c, 1, 1, stuff->get_stream()) == 1
                            && !ferror(stuff->get_stream())
                            && !feof(stuff->get_stream()));
@@ -219,7 +244,49 @@ class HTTPConnectTest: public TestFixture {
             delete stuff; stuff = 0;
             throw;
         }
+    }
+
+    void fetch_url_test_1_cpp() {
+        DBG(cerr << "Entering fetch_url_test 1" << endl);
+        HTTPResponse *stuff = 0;
+        http->set_use_cpp_streams(true);
+        char c;
+        try {
+            stuff = http->fetch_url(localhost_url);
+            stuff->get_cpp_stream()->read(&c, 1);
+            CPPUNIT_ASSERT(*(stuff->get_cpp_stream()));
+            CPPUNIT_ASSERT(!stuff->get_cpp_stream()->bad());
+            CPPUNIT_ASSERT(!stuff->get_cpp_stream()->eof());
+
+            delete stuff;
+        }
+        catch(InternalErr &e) {
+            delete stuff;
+            CPPUNIT_FAIL("Caught an InternalErr from fetch_url: " + e.get_error_message());
+        }
+        catch(Error &e) {
+            delete stuff;
+            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
+        }
+        catch(std::exception &e) {
+            delete stuff;
+            CPPUNIT_FAIL(string("Caught an std::exception from fetch_url: ") + e.what());
+        }
+        // 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 (...) {
+            cerr << "Caught unknown exception" << endl;
+            delete stuff;
+            throw;
+        }
+    }
 
+    void fetch_url_test_2() {
+        DBG(cerr << "Entering fetch_url_test 2" << endl);
+        HTTPResponse *stuff = 0;
+        char c;
         try {
             stuff = http->fetch_url(netcdf_das_url);
             DBG2(char ln[1024]; while (!feof(stuff->get_stream())) {
@@ -250,7 +317,51 @@ class HTTPConnectTest: public TestFixture {
             delete stuff; stuff = 0;
             throw;
         }
+    }
+
+	void fetch_url_test_2_cpp() {
+		DBG(cerr << "Entering fetch_url_test 2" << endl);
+		http->set_use_cpp_streams(true);
+
+		HTTPResponse *stuff = 0;
+		char c;
+
+		try {
+			stuff = http->fetch_url(netcdf_das_url);
+
+            stuff->get_cpp_stream()->read(&c, 1);
+            CPPUNIT_ASSERT(*(stuff->get_cpp_stream())
+            		&& !stuff->get_cpp_stream()->bad()
+            		&& !stuff->get_cpp_stream()->eof());
+
+			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 fetch_url_test_3() {
+        DBG(cerr << "Entering fetch_url_test 3" << endl);
+        HTTPResponse *stuff = 0;
+        char c;
         try {
             stuff = http->fetch_url("file:///etc/passwd");
             CPPUNIT_ASSERT(fread(&c, 1, 1, stuff->get_stream()) == 1
@@ -277,7 +388,49 @@ class HTTPConnectTest: public TestFixture {
             delete stuff; stuff = 0;
             throw;
         }
+    }
+
+    void fetch_url_test_3_cpp() {
+        DBG(cerr << "Entering fetch_url_test 3" << endl);
+		http->set_use_cpp_streams(true);
+
+        HTTPResponse *stuff = 0;
+        char c;
+        try {
+            stuff = http->fetch_url("file:///etc/passwd");
+
+            stuff->get_cpp_stream()->read(&c, 1);
+            CPPUNIT_ASSERT(*(stuff->get_cpp_stream())
+            		&& !stuff->get_cpp_stream()->bad()
+            		&& !stuff->get_cpp_stream()->eof());
+
+            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 fetch_url_test_4() {
+        DBG(cerr << "Entering fetch_url_test 4" << endl);
+        HTTPResponse *stuff = 0;
+        char c;
         try {
 	    string url = (string)"file://test_config.h" ;
             stuff = http->fetch_url(url);
@@ -307,6 +460,44 @@ class HTTPConnectTest: public TestFixture {
         }
     }
 
+    void fetch_url_test_4_cpp() {
+        DBG(cerr << "Entering fetch_url_test 4" << endl);
+		http->set_use_cpp_streams(true);
+
+        HTTPResponse *stuff = 0;
+        char c;
+        try {
+	    string url = (string)"file://test_config.h" ;
+            stuff = http->fetch_url(url);
+
+            stuff->get_cpp_stream()->read(&c, 1);
+            CPPUNIT_ASSERT(*(stuff->get_cpp_stream())
+            		&& !stuff->get_cpp_stream()->bad()
+            		&& !stuff->get_cpp_stream()->eof());
+
+            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;
 
@@ -322,7 +513,7 @@ class HTTPConnectTest: public TestFixture {
 
             CPPUNIT_ASSERT(find_if(h->begin(), h->end(), REMatch(header)) != h->end());
 
-            Regex protocol_header("XDAP: .*");
+            Regex protocol_header("X.*DAP: .*");	// Matches both XDAP and X-DAP
             CPPUNIT_ASSERT(find_if(h->begin(), h->end(), REMatch(protocol_header)) != h->end());
 
             delete r;
@@ -400,35 +591,68 @@ class HTTPConnectTest: public TestFixture {
         }
     }
 
-    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);
+	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_4();
+			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());
+		}
 	}
-	catch (Error &e) {
-	    CPPUNIT_FAIL((string)"Error: " + e.get_error_message());
+
+	void cache_test_cpp()
+	{
+		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_4_cpp();
+			DBG(cerr << "fetch_url_test_4_cpp" << 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() {
+	void set_accept_deflate_test() {
         http->set_accept_deflate(false);
         CPPUNIT_ASSERT(count(http->d_request_headers.begin(),
                              http->d_request_headers.end(),
@@ -500,48 +724,42 @@ class HTTPConnectTest: public TestFixture {
         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 **)
-{
+int main(int argc, char*argv[]) {
     CppUnit::TextTestRunner runner;
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
 
-    cerr << "These tests require a working network connection." << endl;
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = 1;  // debug is a static global
+            break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::HTTPConnectTest::") + argv[i++];
 
-    bool wasSuccessful = runner.run("", false);
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
 
     return wasSuccessful ? 0 : 1;
 }
diff --git a/unit-tests/MIMEUtilTest.cc b/unit-tests/MIMEUtilTest.cc
index 3b256b5..0cb1e65 100644
--- a/unit-tests/MIMEUtilTest.cc
+++ b/unit-tests/MIMEUtilTest.cc
@@ -42,9 +42,10 @@
 
 #include "GNURegex.h"
 
+#include "Error.h"
 #include "mime_util.h"
 #include "debug.h"
-#include <test_config.h>
+#include "test_config.h"
 
 using namespace CppUnit;
 using namespace std;
@@ -191,7 +192,7 @@ Content-Description: dods_dds\r\n\
 	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-Description: dods-ddx");
 	    CPPUNIT_ASSERT(get_next_mime_header(in) == "Content-Id: <1234 at opendap.org>");
 	}
 	catch (Error &e) {
@@ -210,7 +211,7 @@ Content-Description: dods_dds\r\n\
 	    CPPUNIT_FAIL("Could not open the mime header file.");
 
 	try {
-	    read_multipart_headers(in, "text/xml", dap4_ddx);
+	    read_multipart_headers(in, "text/xml", dods_ddx);
 	    CPPUNIT_ASSERT(true);
 	}
 	catch (Error &e) {
diff --git a/unit-tests/Makefile.am b/unit-tests/Makefile.am
index 0551973..32cb54b 100644
--- a/unit-tests/Makefile.am
+++ b/unit-tests/Makefile.am
@@ -9,15 +9,31 @@ AUTOMAKE_OPTIONS = foreign
 
 AM_CPPFLAGS = -I$(top_srcdir)/GNU -I$(top_srcdir) -I$(top_srcdir)/tests $(CURL_CFLAGS) $(XML2_CFLAGS)
 AM_LDADD =
+AM_CXXFLAGS = 
+CXXFLAGS = 
+
+if COMPILER_IS_GCC
+AM_CXXFLAGS += -Wall -W -Wcast-align
+endif
+
 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  -Wall -W -Wcast-align -Werror
-TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
+CXXFLAGS_DEBUG = -g3 -O0 -Wall -Wcast-align
+
+if USE_VALGRIND
+TESTS_ENVIRONMENT=valgrind --quiet --trace-children=yes --error-exitcode=1 \
+--leak-check=yes --dsymutil=yes --suppressions=valgrind_suppressions.txt
+
+# skip using --log-file="valgrind-%p.log" because it always generates files
+# Might also drop --dsymutil=yes because it can take a long time to run.
+endif
+
+if BUILD_DEVELOPER
+AM_CXXFLAGS += $(CXXFLAGS_DEBUG)
+endif
 
 # This determines what gets built by make check
 check_PROGRAMS = $(UNIT_TESTS)
@@ -28,35 +44,36 @@ TESTS = $(UNIT_TESTS)
 noinst_HEADERS = test_config.h
 
 DIRS_EXTRA = das-testsuite dds-testsuite ddx-testsuite		\
-	rcreader-testsuite server-testsuite cgi-util-tests D4-xml
+	rcreader-testsuite server-testsuite cgi-util-tests D4-xml \
+	chunked-io D4-marshaller
 
 EXTRA_DIST = $(DIRS_EXTRA) testFile.cc testFile.h test_config.h.in
 
-CLEANFILES = testout .dodsrc  *.gcda *.gcno
+CLEANFILES = testout .dodsrc  *.gcda *.gcno D4-xml.tar.gz
 
 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
 
+D4-xml.tar.gz: D4-xml/DMR_*[0-9].xml
+	tar -czf $@ $^
+
 ############################################################################
 # Unit Tests
 #
 
 if CPPUNIT
-UNIT_TESTS = marshT arrayT attrTableT structT sequenceT ddsT dasT	\
-	RegexTest                                                       \
-	ArrayTest AttrTableTest ByteTest MIMEUtilTest ancT DASTest 	\
-	DDSTest	DDXParserTest generalUtilTest 		\
-	HTTPCacheTest HTTPConnectTest parserUtilTest RCReaderTest 	\
-	SequenceTest SignalHandlerTest  MarshallerTest                  \
-	ServerFunctionsListUnitTest 
-	
-# ResponseBuilderTest ResponseCacheTest Keywords2Test DODSFilterTest 
-	
+UNIT_TESTS = marshT arrayT attrTableT structT sequenceT ddsT dasT \
+	RegexTest ArrayTest AttrTableTest ByteTest MIMEUtilTest ancT DASTest \
+	DDSTest	DDXParserTest  generalUtilTest HTTPConnectTest parserUtilTest \
+	RCReaderTest SequenceTest SignalHandlerTest  MarshallerTest \
+	HTTPCacheTest ServerFunctionsListUnitTest 
+
 if DAP4_DEFINED
-    UNIT_TESTS += DAP4MarshallerTest DAP4UnMarshallerTest \
-    D4DimensionsTest D4EnumDefsTest
+UNIT_TESTS += D4MarshallerTest D4UnMarshallerTest D4DimensionsTest \
+	D4EnumDefsTest D4GroupTest D4ParserSax2Test D4AttributesTest D4EnumTest \
+	chunked_iostream_test D4AsyncDocTest DMRTest
 endif
 
 else
@@ -167,11 +184,11 @@ ServerFunctionsListUnitTest_LDADD = ../libdap.la $(AM_LDADD)
 
 if DAP4_DEFINED
 
-DAP4MarshallerTest_SOURCES = DAP4MarshallerTest.cc
-DAP4MarshallerTest_LDADD = ../libdap.la $(AM_LDADD)
+D4MarshallerTest_SOURCES = D4MarshallerTest.cc
+D4MarshallerTest_LDADD = ../libdap.la $(AM_LDADD)
 
-DAP4UnMarshallerTest_SOURCES = DAP4UnMarshallerTest.cc
-DAP4UnMarshallerTest_LDADD = ../libdap.la $(AM_LDADD)
+D4UnMarshallerTest_SOURCES = D4UnMarshallerTest.cc
+D4UnMarshallerTest_LDADD = ../libdap.la $(AM_LDADD)
 
 D4DimensionsTest_SOURCES = D4DimensionsTest.cc $(TEST_SRC)
 D4DimensionsTest_LDADD = ../libdap.la $(AM_LDADD)
@@ -179,4 +196,25 @@ D4DimensionsTest_LDADD = ../libdap.la $(AM_LDADD)
 D4EnumDefsTest_SOURCES = D4EnumDefsTest.cc $(TEST_SRC)
 D4EnumDefsTest_LDADD = ../libdap.la $(AM_LDADD)
 
+D4GroupTest_SOURCES = D4GroupTest.cc $(TEST_SRC)
+D4GroupTest_LDADD = ../libdap.la $(AM_LDADD)
+
+D4ParserSax2Test_SOURCES = D4ParserSax2Test.cc $(TEST_SRC)
+D4ParserSax2Test_LDADD = ../libdap.la $(AM_LDADD)
+
+D4AttributesTest_SOURCES = D4AttributesTest.cc $(TEST_SRC)
+D4AttributesTest_LDADD = ../libdap.la $(AM_LDADD)
+
+D4EnumTest_SOURCES = D4EnumTest.cc $(TEST_SRC)
+D4EnumTest_LDADD = ../libdap.la $(AM_LDADD)
+
+chunked_iostream_test_SOURCES = chunked_iostream_test.cc $(TEST_SRC)
+chunked_iostream_test_LDADD = ../libdap.la $(AM_LDADD)
+
+D4AsyncDocTest_SOURCES = D4AsyncDocTest.cc $(TEST_SRC)
+D4AsyncDocTest_LDADD = ../libdap.la $(AM_LDADD)
+
+DMRTest_SOURCES = DMRTest.cc $(TEST_SRC)
+DMRTest_LDADD = ../libdap.la $(AM_LDADD)
+
 endif
diff --git a/unit-tests/Makefile.in b/unit-tests/Makefile.in
index a399ca7..4d6081b 100644
--- a/unit-tests/Makefile.in
+++ b/unit-tests/Makefile.in
@@ -50,14 +50,18 @@ 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)
+ at COMPILER_IS_GCC_TRUE@am__append_1 = -Wall -W -Wcast-align
+ at CPPUNIT_TRUE@am__append_2 = $(CPPUNIT_CFLAGS)
+ at CPPUNIT_TRUE@am__append_3 = $(CPPUNIT_LIBS)
+
+# skip using --log-file="valgrind-%p.log" because it always generates files
+# Might also drop --dsymutil=yes because it can take a long time to run.
+ at BUILD_DEVELOPER_TRUE@am__append_4 = $(CXXFLAGS_DEBUG)
 check_PROGRAMS = $(am__EXEEXT_2)
 TESTS = $(am__EXEEXT_2)
-
-# ResponseBuilderTest ResponseCacheTest Keywords2Test DODSFilterTest 
- at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE at am__append_3 = DAP4MarshallerTest DAP4UnMarshallerTest \
- at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@    D4DimensionsTest D4EnumDefsTest
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE at am__append_5 = D4MarshallerTest D4UnMarshallerTest D4DimensionsTest \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4EnumDefsTest D4GroupTest D4ParserSax2Test D4AttributesTest D4EnumTest \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	chunked_iostream_test D4AsyncDocTest DMRTest
 
 subdir = unit-tests
 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
@@ -67,19 +71,23 @@ 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/byteswap.m4 $(top_srcdir)/gl/m4/codeset.m4 \
 	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/eealloc.m4 \
 	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/extern-inline.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/lib-ld.m4 $(top_srcdir)/gl/m4/lib-link.m4 \
+	$(top_srcdir)/gl/m4/lib-prefix.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/locale_h.m4 \
-	$(top_srcdir)/gl/m4/localeconv.m4 \
+	$(top_srcdir)/gl/m4/localeconv.m4 $(top_srcdir)/gl/m4/lock.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/mbtowc.m4 \
@@ -88,17 +96,18 @@ am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
 	$(top_srcdir)/gl/m4/off_t.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/strcase.m4 \
-	$(top_srcdir)/gl/m4/strings_h.m4 \
+	$(top_srcdir)/gl/m4/stdlib_h.m4 \
 	$(top_srcdir)/gl/m4/sys_types_h.m4 \
+	$(top_srcdir)/gl/m4/threadlib.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/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/cppunit.m4 \
+	$(top_srcdir)/conf/gcov_valgrind.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) \
@@ -110,10 +119,17 @@ CONFIG_HEADER = $(top_builddir)/config.h \
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 @CPPUNIT_TRUE@@DAP4_DEFINED_TRUE at am__EXEEXT_1 =  \
- at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	DAP4MarshallerTest$(EXEEXT) \
- at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	DAP4UnMarshallerTest$(EXEEXT) \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4MarshallerTest$(EXEEXT) \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4UnMarshallerTest$(EXEEXT) \
 @CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4DimensionsTest$(EXEEXT) \
- at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4EnumDefsTest$(EXEEXT)
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4EnumDefsTest$(EXEEXT) \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4GroupTest$(EXEEXT) \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4ParserSax2Test$(EXEEXT) \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4AttributesTest$(EXEEXT) \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4EnumTest$(EXEEXT) \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	chunked_iostream_test$(EXEEXT) \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	D4AsyncDocTest$(EXEEXT) \
+ at CPPUNIT_TRUE@@DAP4_DEFINED_TRUE@	DMRTest$(EXEEXT)
 @CPPUNIT_TRUE at am__EXEEXT_2 = marshT$(EXEEXT) arrayT$(EXEEXT) \
 @CPPUNIT_TRUE@	attrTableT$(EXEEXT) structT$(EXEEXT) \
 @CPPUNIT_TRUE@	sequenceT$(EXEEXT) ddsT$(EXEEXT) dasT$(EXEEXT) \
@@ -122,10 +138,10 @@ CONFIG_CLEAN_VPATH_FILES =
 @CPPUNIT_TRUE@	MIMEUtilTest$(EXEEXT) ancT$(EXEEXT) \
 @CPPUNIT_TRUE@	DASTest$(EXEEXT) DDSTest$(EXEEXT) \
 @CPPUNIT_TRUE@	DDXParserTest$(EXEEXT) generalUtilTest$(EXEEXT) \
- at CPPUNIT_TRUE@	HTTPCacheTest$(EXEEXT) HTTPConnectTest$(EXEEXT) \
- at CPPUNIT_TRUE@	parserUtilTest$(EXEEXT) RCReaderTest$(EXEEXT) \
- at CPPUNIT_TRUE@	SequenceTest$(EXEEXT) SignalHandlerTest$(EXEEXT) \
- at CPPUNIT_TRUE@	MarshallerTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	HTTPConnectTest$(EXEEXT) parserUtilTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	RCReaderTest$(EXEEXT) SequenceTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	SignalHandlerTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	MarshallerTest$(EXEEXT) HTTPCacheTest$(EXEEXT) \
 @CPPUNIT_TRUE@	ServerFunctionsListUnitTest$(EXEEXT) \
 @CPPUNIT_TRUE@	$(am__EXEEXT_1)
 am_ArrayTest_OBJECTS = ArrayTest.$(OBJEXT)
@@ -141,6 +157,20 @@ AttrTableTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
 am_ByteTest_OBJECTS = ByteTest.$(OBJEXT) $(am__objects_1)
 ByteTest_OBJECTS = $(am_ByteTest_OBJECTS)
 ByteTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am__D4AsyncDocTest_SOURCES_DIST = D4AsyncDocTest.cc testFile.cc \
+	testFile.h
+ at DAP4_DEFINED_TRUE@am_D4AsyncDocTest_OBJECTS =  \
+ at DAP4_DEFINED_TRUE@	D4AsyncDocTest.$(OBJEXT) $(am__objects_1)
+D4AsyncDocTest_OBJECTS = $(am_D4AsyncDocTest_OBJECTS)
+ at DAP4_DEFINED_TRUE@D4AsyncDocTest_DEPENDENCIES = ../libdap.la \
+ at DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
+am__D4AttributesTest_SOURCES_DIST = D4AttributesTest.cc testFile.cc \
+	testFile.h
+ at DAP4_DEFINED_TRUE@am_D4AttributesTest_OBJECTS =  \
+ at DAP4_DEFINED_TRUE@	D4AttributesTest.$(OBJEXT) $(am__objects_1)
+D4AttributesTest_OBJECTS = $(am_D4AttributesTest_OBJECTS)
+ at DAP4_DEFINED_TRUE@D4AttributesTest_DEPENDENCIES = ../libdap.la \
+ at DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
 am__D4DimensionsTest_SOURCES_DIST = D4DimensionsTest.cc testFile.cc \
 	testFile.h
 @DAP4_DEFINED_TRUE at am_D4DimensionsTest_OBJECTS =  \
@@ -155,17 +185,36 @@ am__D4EnumDefsTest_SOURCES_DIST = D4EnumDefsTest.cc testFile.cc \
 D4EnumDefsTest_OBJECTS = $(am_D4EnumDefsTest_OBJECTS)
 @DAP4_DEFINED_TRUE at D4EnumDefsTest_DEPENDENCIES = ../libdap.la \
 @DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
-am__DAP4MarshallerTest_SOURCES_DIST = DAP4MarshallerTest.cc
- at DAP4_DEFINED_TRUE@am_DAP4MarshallerTest_OBJECTS =  \
- at DAP4_DEFINED_TRUE@	DAP4MarshallerTest.$(OBJEXT)
-DAP4MarshallerTest_OBJECTS = $(am_DAP4MarshallerTest_OBJECTS)
- at DAP4_DEFINED_TRUE@DAP4MarshallerTest_DEPENDENCIES = ../libdap.la \
+am__D4EnumTest_SOURCES_DIST = D4EnumTest.cc testFile.cc testFile.h
+ at DAP4_DEFINED_TRUE@am_D4EnumTest_OBJECTS = D4EnumTest.$(OBJEXT) \
+ at DAP4_DEFINED_TRUE@	$(am__objects_1)
+D4EnumTest_OBJECTS = $(am_D4EnumTest_OBJECTS)
+ at DAP4_DEFINED_TRUE@D4EnumTest_DEPENDENCIES = ../libdap.la \
+ at DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
+am__D4GroupTest_SOURCES_DIST = D4GroupTest.cc testFile.cc testFile.h
+ at DAP4_DEFINED_TRUE@am_D4GroupTest_OBJECTS = D4GroupTest.$(OBJEXT) \
+ at DAP4_DEFINED_TRUE@	$(am__objects_1)
+D4GroupTest_OBJECTS = $(am_D4GroupTest_OBJECTS)
+ at DAP4_DEFINED_TRUE@D4GroupTest_DEPENDENCIES = ../libdap.la \
+ at DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
+am__D4MarshallerTest_SOURCES_DIST = D4MarshallerTest.cc
+ at DAP4_DEFINED_TRUE@am_D4MarshallerTest_OBJECTS =  \
+ at DAP4_DEFINED_TRUE@	D4MarshallerTest.$(OBJEXT)
+D4MarshallerTest_OBJECTS = $(am_D4MarshallerTest_OBJECTS)
+ at DAP4_DEFINED_TRUE@D4MarshallerTest_DEPENDENCIES = ../libdap.la \
 @DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
-am__DAP4UnMarshallerTest_SOURCES_DIST = DAP4UnMarshallerTest.cc
- at DAP4_DEFINED_TRUE@am_DAP4UnMarshallerTest_OBJECTS =  \
- at DAP4_DEFINED_TRUE@	DAP4UnMarshallerTest.$(OBJEXT)
-DAP4UnMarshallerTest_OBJECTS = $(am_DAP4UnMarshallerTest_OBJECTS)
- at DAP4_DEFINED_TRUE@DAP4UnMarshallerTest_DEPENDENCIES = ../libdap.la \
+am__D4ParserSax2Test_SOURCES_DIST = D4ParserSax2Test.cc testFile.cc \
+	testFile.h
+ at DAP4_DEFINED_TRUE@am_D4ParserSax2Test_OBJECTS =  \
+ at DAP4_DEFINED_TRUE@	D4ParserSax2Test.$(OBJEXT) $(am__objects_1)
+D4ParserSax2Test_OBJECTS = $(am_D4ParserSax2Test_OBJECTS)
+ at DAP4_DEFINED_TRUE@D4ParserSax2Test_DEPENDENCIES = ../libdap.la \
+ at DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
+am__D4UnMarshallerTest_SOURCES_DIST = D4UnMarshallerTest.cc
+ at DAP4_DEFINED_TRUE@am_D4UnMarshallerTest_OBJECTS =  \
+ at DAP4_DEFINED_TRUE@	D4UnMarshallerTest.$(OBJEXT)
+D4UnMarshallerTest_OBJECTS = $(am_D4UnMarshallerTest_OBJECTS)
+ at DAP4_DEFINED_TRUE@D4UnMarshallerTest_DEPENDENCIES = ../libdap.la \
 @DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
 am_DASTest_OBJECTS = DASTest.$(OBJEXT)
 DASTest_OBJECTS = $(am_DASTest_OBJECTS)
@@ -176,6 +225,12 @@ 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__DMRTest_SOURCES_DIST = DMRTest.cc testFile.cc testFile.h
+ at DAP4_DEFINED_TRUE@am_DMRTest_OBJECTS = DMRTest.$(OBJEXT) \
+ at DAP4_DEFINED_TRUE@	$(am__objects_1)
+DMRTest_OBJECTS = $(am_DMRTest_OBJECTS)
+ at DAP4_DEFINED_TRUE@DMRTest_DEPENDENCIES = ../libdap.la \
+ at DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
 am_HTTPCacheTest_OBJECTS = HTTPCacheTest-HTTPCacheTest.$(OBJEXT)
 HTTPCacheTest_OBJECTS = $(am_HTTPCacheTest_OBJECTS)
 HTTPCacheTest_DEPENDENCIES = ../libdapclient.la ../libdap.la \
@@ -224,6 +279,14 @@ am_attrTableT_OBJECTS = attrTableT.$(OBJEXT)
 attrTableT_OBJECTS = $(am_attrTableT_OBJECTS)
 attrTableT_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
 	$(am__DEPENDENCIES_3)
+am__chunked_iostream_test_SOURCES_DIST = chunked_iostream_test.cc \
+	testFile.cc testFile.h
+ at DAP4_DEFINED_TRUE@am_chunked_iostream_test_OBJECTS =  \
+ at DAP4_DEFINED_TRUE@	chunked_iostream_test.$(OBJEXT) \
+ at DAP4_DEFINED_TRUE@	$(am__objects_1)
+chunked_iostream_test_OBJECTS = $(am_chunked_iostream_test_OBJECTS)
+ at DAP4_DEFINED_TRUE@chunked_iostream_test_DEPENDENCIES = ../libdap.la \
+ at DAP4_DEFINED_TRUE@	$(am__DEPENDENCIES_3)
 am_dasT_OBJECTS = dasT.$(OBJEXT) $(am__objects_1)
 dasT_OBJECTS = $(am_dasT_OBJECTS)
 dasT_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
@@ -273,32 +336,41 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
 SOURCES = $(ArrayTest_SOURCES) $(AttrTableTest_SOURCES) \
-	$(ByteTest_SOURCES) $(D4DimensionsTest_SOURCES) \
-	$(D4EnumDefsTest_SOURCES) $(DAP4MarshallerTest_SOURCES) \
-	$(DAP4UnMarshallerTest_SOURCES) $(DASTest_SOURCES) \
-	$(DDSTest_SOURCES) $(DDXParserTest_SOURCES) \
-	$(HTTPCacheTest_SOURCES) $(HTTPConnectTest_SOURCES) \
-	$(MIMEUtilTest_SOURCES) $(MarshallerTest_SOURCES) \
-	$(RCReaderTest_SOURCES) $(RegexTest_SOURCES) \
-	$(SequenceTest_SOURCES) $(ServerFunctionsListUnitTest_SOURCES) \
+	$(ByteTest_SOURCES) $(D4AsyncDocTest_SOURCES) \
+	$(D4AttributesTest_SOURCES) $(D4DimensionsTest_SOURCES) \
+	$(D4EnumDefsTest_SOURCES) $(D4EnumTest_SOURCES) \
+	$(D4GroupTest_SOURCES) $(D4MarshallerTest_SOURCES) \
+	$(D4ParserSax2Test_SOURCES) $(D4UnMarshallerTest_SOURCES) \
+	$(DASTest_SOURCES) $(DDSTest_SOURCES) $(DDXParserTest_SOURCES) \
+	$(DMRTest_SOURCES) $(HTTPCacheTest_SOURCES) \
+	$(HTTPConnectTest_SOURCES) $(MIMEUtilTest_SOURCES) \
+	$(MarshallerTest_SOURCES) $(RCReaderTest_SOURCES) \
+	$(RegexTest_SOURCES) $(SequenceTest_SOURCES) \
+	$(ServerFunctionsListUnitTest_SOURCES) \
 	$(SignalHandlerTest_SOURCES) $(ancT_SOURCES) $(arrayT_SOURCES) \
-	$(attrTableT_SOURCES) $(dasT_SOURCES) $(ddsT_SOURCES) \
-	$(generalUtilTest_SOURCES) $(marshT_SOURCES) \
-	$(parserUtilTest_SOURCES) $(sequenceT_SOURCES) \
-	$(structT_SOURCES)
+	$(attrTableT_SOURCES) $(chunked_iostream_test_SOURCES) \
+	$(dasT_SOURCES) $(ddsT_SOURCES) $(generalUtilTest_SOURCES) \
+	$(marshT_SOURCES) $(parserUtilTest_SOURCES) \
+	$(sequenceT_SOURCES) $(structT_SOURCES)
 DIST_SOURCES = $(ArrayTest_SOURCES) $(AttrTableTest_SOURCES) \
-	$(ByteTest_SOURCES) $(am__D4DimensionsTest_SOURCES_DIST) \
+	$(ByteTest_SOURCES) $(am__D4AsyncDocTest_SOURCES_DIST) \
+	$(am__D4AttributesTest_SOURCES_DIST) \
+	$(am__D4DimensionsTest_SOURCES_DIST) \
 	$(am__D4EnumDefsTest_SOURCES_DIST) \
-	$(am__DAP4MarshallerTest_SOURCES_DIST) \
-	$(am__DAP4UnMarshallerTest_SOURCES_DIST) $(DASTest_SOURCES) \
+	$(am__D4EnumTest_SOURCES_DIST) $(am__D4GroupTest_SOURCES_DIST) \
+	$(am__D4MarshallerTest_SOURCES_DIST) \
+	$(am__D4ParserSax2Test_SOURCES_DIST) \
+	$(am__D4UnMarshallerTest_SOURCES_DIST) $(DASTest_SOURCES) \
 	$(DDSTest_SOURCES) $(DDXParserTest_SOURCES) \
-	$(HTTPCacheTest_SOURCES) $(HTTPConnectTest_SOURCES) \
-	$(MIMEUtilTest_SOURCES) $(MarshallerTest_SOURCES) \
-	$(RCReaderTest_SOURCES) $(RegexTest_SOURCES) \
-	$(SequenceTest_SOURCES) $(ServerFunctionsListUnitTest_SOURCES) \
+	$(am__DMRTest_SOURCES_DIST) $(HTTPCacheTest_SOURCES) \
+	$(HTTPConnectTest_SOURCES) $(MIMEUtilTest_SOURCES) \
+	$(MarshallerTest_SOURCES) $(RCReaderTest_SOURCES) \
+	$(RegexTest_SOURCES) $(SequenceTest_SOURCES) \
+	$(ServerFunctionsListUnitTest_SOURCES) \
 	$(SignalHandlerTest_SOURCES) $(ancT_SOURCES) $(arrayT_SOURCES) \
-	$(attrTableT_SOURCES) $(dasT_SOURCES) $(ddsT_SOURCES) \
-	$(generalUtilTest_SOURCES) $(marshT_SOURCES) \
+	$(attrTableT_SOURCES) \
+	$(am__chunked_iostream_test_SOURCES_DIST) $(dasT_SOURCES) \
+	$(ddsT_SOURCES) $(generalUtilTest_SOURCES) $(marshT_SOURCES) \
 	$(parserUtilTest_SOURCES) $(sequenceT_SOURCES) \
 	$(structT_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
@@ -388,7 +460,7 @@ CURL_STATIC_LIBS = @CURL_STATIC_LIBS@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
+CXXFLAGS = 
 CYGPATH_W = @CYGPATH_W@
 DAPLIB_AGE = @DAPLIB_AGE@
 DAPLIB_CURRENT = @DAPLIB_CURRENT@
@@ -404,7 +476,6 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
-EVAL = @EVAL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GLIBC21 = @GLIBC21@
@@ -425,7 +496,6 @@ GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
 GNULIB_FCHDIR = @GNULIB_FCHDIR@
 GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
 GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
-GNULIB_FFS = @GNULIB_FFS@
 GNULIB_FSYNC = @GNULIB_FSYNC@
 GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
 GNULIB_GETCWD = @GNULIB_GETCWD@
@@ -479,6 +549,7 @@ GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
 GNULIB_REALPATH = @GNULIB_REALPATH@
 GNULIB_RMDIR = @GNULIB_RMDIR@
 GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
 GNULIB_SETENV = @GNULIB_SETENV@
 GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
 GNULIB_SETLOCALE = @GNULIB_SETLOCALE@
@@ -551,7 +622,6 @@ HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
 HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
 HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
 HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
-HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
 HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
 HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
 HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
@@ -565,7 +635,6 @@ HAVE_FCHDIR = @HAVE_FCHDIR@
 HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
 HAVE_FDATASYNC = @HAVE_FDATASYNC@
 HAVE_FEATURES_H = @HAVE_FEATURES_H@
-HAVE_FFS = @HAVE_FFS@
 HAVE_FSYNC = @HAVE_FSYNC@
 HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
 HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
@@ -614,6 +683,7 @@ HAVE_READLINK = @HAVE_READLINK@
 HAVE_READLINKAT = @HAVE_READLINKAT@
 HAVE_REALPATH = @HAVE_REALPATH@
 HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
 HAVE_SETENV = @HAVE_SETENV@
 HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
 HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
@@ -621,8 +691,6 @@ 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_STRCASECMP = @HAVE_STRCASECMP@
-HAVE_STRINGS_H = @HAVE_STRINGS_H@
 HAVE_STRTOD = @HAVE_STRTOD@
 HAVE_STRTOLL = @HAVE_STRTOLL@
 HAVE_STRTOULL = @HAVE_STRTOULL@
@@ -639,6 +707,7 @@ HAVE_UNLINKAT = @HAVE_UNLINKAT@
 HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
 HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
 HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_VALGRIND = @HAVE_VALGRIND@
 HAVE_WCHAR_H = @HAVE_WCHAR_H@
 HAVE_WCHAR_T = @HAVE_WCHAR_T@
 HAVE_WCPCPY = @HAVE_WCPCPY@
@@ -693,8 +762,12 @@ LEXLIB = @LEXLIB@
 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
 LIBDAP_VERSION = @LIBDAP_VERSION@
 LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
 LIBS = @LIBS@
+LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -704,7 +777,10 @@ LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
 LOCALE_JA = @LOCALE_JA@
 LOCALE_ZH_CN = @LOCALE_ZH_CN@
 LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -713,7 +789,6 @@ NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_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_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
 NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_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@
@@ -723,7 +798,6 @@ NEXT_LOCALE_H = @NEXT_LOCALE_H@
 NEXT_STDDEF_H = @NEXT_STDDEF_H@
 NEXT_STDINT_H = @NEXT_STDINT_H@
 NEXT_STDLIB_H = @NEXT_STDLIB_H@
-NEXT_STRINGS_H = @NEXT_STRINGS_H@
 NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
 NEXT_UNISTD_H = @NEXT_UNISTD_H@
 NEXT_WCHAR_H = @NEXT_WCHAR_H@
@@ -763,6 +837,7 @@ REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
 REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
 REPLACE_GETCWD = @REPLACE_GETCWD@
 REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
 REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
 REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
 REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
@@ -786,6 +861,7 @@ REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
 REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
 REPLACE_NULL = @REPLACE_NULL@
 REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
 REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
 REPLACE_PUTENV = @REPLACE_PUTENV@
 REPLACE_PWRITE = @REPLACE_PWRITE@
@@ -891,6 +967,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -909,19 +986,20 @@ 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 $(CURL_CFLAGS) $(XML2_CFLAGS) \
-	$(am__append_1)
-AM_LDADD = $(am__append_2)
+	$(am__append_2)
+AM_LDADD = $(am__append_3)
+AM_CXXFLAGS = $(am__append_1) $(am__append_4)
+CXXFLAGS_DEBUG = -g3 -O0 -Wall -Wcast-align
+ at USE_VALGRIND_TRUE@TESTS_ENVIRONMENT = valgrind --quiet --trace-children=yes --error-exitcode=1 \
+ at USE_VALGRIND_TRUE@--leak-check=yes --dsymutil=yes --suppressions=valgrind_suppressions.txt
 
-# 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  -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 D4-xml
+	rcreader-testsuite server-testsuite cgi-util-tests D4-xml \
+	chunked-io D4-marshaller
 
 EXTRA_DIST = $(DIRS_EXTRA) testFile.cc testFile.h test_config.h.in
-CLEANFILES = testout .dodsrc  *.gcda *.gcno
+CLEANFILES = testout .dodsrc  *.gcda *.gcno D4-xml.tar.gz
 DISTCLEANFILES = test_config.h *.strm *.file tmp.txt
 @CPPUNIT_FALSE at UNIT_TESTS = 
 
@@ -931,10 +1009,10 @@ DISTCLEANFILES = test_config.h *.strm *.file tmp.txt
 @CPPUNIT_TRUE at UNIT_TESTS = marshT arrayT attrTableT structT sequenceT \
 @CPPUNIT_TRUE@	ddsT dasT RegexTest ArrayTest AttrTableTest \
 @CPPUNIT_TRUE@	ByteTest MIMEUtilTest ancT DASTest DDSTest \
- at CPPUNIT_TRUE@	DDXParserTest generalUtilTest HTTPCacheTest \
- at CPPUNIT_TRUE@	HTTPConnectTest parserUtilTest RCReaderTest \
- at CPPUNIT_TRUE@	SequenceTest SignalHandlerTest MarshallerTest \
- at CPPUNIT_TRUE@	ServerFunctionsListUnitTest $(am__append_3)
+ at CPPUNIT_TRUE@	DDXParserTest generalUtilTest HTTPConnectTest \
+ at CPPUNIT_TRUE@	parserUtilTest RCReaderTest SequenceTest \
+ at CPPUNIT_TRUE@	SignalHandlerTest MarshallerTest HTTPCacheTest \
+ at CPPUNIT_TRUE@	ServerFunctionsListUnitTest $(am__append_5)
 TEST_SRC = testFile.cc testFile.h
 RegexTest_SOURCES = RegexTest.cc
 RegexTest_LDADD = ../libdap.la $(AM_LDADD)
@@ -1003,14 +1081,28 @@ ServerFunctionsListUnitTest_LDADD = ../libdap.la $(AM_LDADD)
 
 # ResponseCacheTest_SOURCES = ResponseCacheTest.cc
 # ResponseCacheTest_LDADD = ../tests/libtest-types.a ../libdapserver.la ../libdap.la $(AM_LDADD)
- at DAP4_DEFINED_TRUE@DAP4MarshallerTest_SOURCES = DAP4MarshallerTest.cc
- at DAP4_DEFINED_TRUE@DAP4MarshallerTest_LDADD = ../libdap.la $(AM_LDADD)
- at DAP4_DEFINED_TRUE@DAP4UnMarshallerTest_SOURCES = DAP4UnMarshallerTest.cc
- at DAP4_DEFINED_TRUE@DAP4UnMarshallerTest_LDADD = ../libdap.la $(AM_LDADD)
+ at DAP4_DEFINED_TRUE@D4MarshallerTest_SOURCES = D4MarshallerTest.cc
+ at DAP4_DEFINED_TRUE@D4MarshallerTest_LDADD = ../libdap.la $(AM_LDADD)
+ at DAP4_DEFINED_TRUE@D4UnMarshallerTest_SOURCES = D4UnMarshallerTest.cc
+ at DAP4_DEFINED_TRUE@D4UnMarshallerTest_LDADD = ../libdap.la $(AM_LDADD)
 @DAP4_DEFINED_TRUE at D4DimensionsTest_SOURCES = D4DimensionsTest.cc $(TEST_SRC)
 @DAP4_DEFINED_TRUE at D4DimensionsTest_LDADD = ../libdap.la $(AM_LDADD)
 @DAP4_DEFINED_TRUE at D4EnumDefsTest_SOURCES = D4EnumDefsTest.cc $(TEST_SRC)
 @DAP4_DEFINED_TRUE at D4EnumDefsTest_LDADD = ../libdap.la $(AM_LDADD)
+ at DAP4_DEFINED_TRUE@D4GroupTest_SOURCES = D4GroupTest.cc $(TEST_SRC)
+ at DAP4_DEFINED_TRUE@D4GroupTest_LDADD = ../libdap.la $(AM_LDADD)
+ at DAP4_DEFINED_TRUE@D4ParserSax2Test_SOURCES = D4ParserSax2Test.cc $(TEST_SRC)
+ at DAP4_DEFINED_TRUE@D4ParserSax2Test_LDADD = ../libdap.la $(AM_LDADD)
+ at DAP4_DEFINED_TRUE@D4AttributesTest_SOURCES = D4AttributesTest.cc $(TEST_SRC)
+ at DAP4_DEFINED_TRUE@D4AttributesTest_LDADD = ../libdap.la $(AM_LDADD)
+ at DAP4_DEFINED_TRUE@D4EnumTest_SOURCES = D4EnumTest.cc $(TEST_SRC)
+ at DAP4_DEFINED_TRUE@D4EnumTest_LDADD = ../libdap.la $(AM_LDADD)
+ at DAP4_DEFINED_TRUE@chunked_iostream_test_SOURCES = chunked_iostream_test.cc $(TEST_SRC)
+ at DAP4_DEFINED_TRUE@chunked_iostream_test_LDADD = ../libdap.la $(AM_LDADD)
+ at DAP4_DEFINED_TRUE@D4AsyncDocTest_SOURCES = D4AsyncDocTest.cc $(TEST_SRC)
+ at DAP4_DEFINED_TRUE@D4AsyncDocTest_LDADD = ../libdap.la $(AM_LDADD)
+ at DAP4_DEFINED_TRUE@DMRTest_SOURCES = DMRTest.cc $(TEST_SRC)
+ at DAP4_DEFINED_TRUE@DMRTest_LDADD = ../libdap.la $(AM_LDADD)
 all: all-recursive
 
 .SUFFIXES:
@@ -1063,18 +1155,33 @@ AttrTableTest$(EXEEXT): $(AttrTableTest_OBJECTS) $(AttrTableTest_DEPENDENCIES) $
 ByteTest$(EXEEXT): $(ByteTest_OBJECTS) $(ByteTest_DEPENDENCIES) $(EXTRA_ByteTest_DEPENDENCIES) 
 	@rm -f ByteTest$(EXEEXT)
 	$(CXXLINK) $(ByteTest_OBJECTS) $(ByteTest_LDADD) $(LIBS)
+D4AsyncDocTest$(EXEEXT): $(D4AsyncDocTest_OBJECTS) $(D4AsyncDocTest_DEPENDENCIES) $(EXTRA_D4AsyncDocTest_DEPENDENCIES) 
+	@rm -f D4AsyncDocTest$(EXEEXT)
+	$(CXXLINK) $(D4AsyncDocTest_OBJECTS) $(D4AsyncDocTest_LDADD) $(LIBS)
+D4AttributesTest$(EXEEXT): $(D4AttributesTest_OBJECTS) $(D4AttributesTest_DEPENDENCIES) $(EXTRA_D4AttributesTest_DEPENDENCIES) 
+	@rm -f D4AttributesTest$(EXEEXT)
+	$(CXXLINK) $(D4AttributesTest_OBJECTS) $(D4AttributesTest_LDADD) $(LIBS)
 D4DimensionsTest$(EXEEXT): $(D4DimensionsTest_OBJECTS) $(D4DimensionsTest_DEPENDENCIES) $(EXTRA_D4DimensionsTest_DEPENDENCIES) 
 	@rm -f D4DimensionsTest$(EXEEXT)
 	$(CXXLINK) $(D4DimensionsTest_OBJECTS) $(D4DimensionsTest_LDADD) $(LIBS)
 D4EnumDefsTest$(EXEEXT): $(D4EnumDefsTest_OBJECTS) $(D4EnumDefsTest_DEPENDENCIES) $(EXTRA_D4EnumDefsTest_DEPENDENCIES) 
 	@rm -f D4EnumDefsTest$(EXEEXT)
 	$(CXXLINK) $(D4EnumDefsTest_OBJECTS) $(D4EnumDefsTest_LDADD) $(LIBS)
-DAP4MarshallerTest$(EXEEXT): $(DAP4MarshallerTest_OBJECTS) $(DAP4MarshallerTest_DEPENDENCIES) $(EXTRA_DAP4MarshallerTest_DEPENDENCIES) 
-	@rm -f DAP4MarshallerTest$(EXEEXT)
-	$(CXXLINK) $(DAP4MarshallerTest_OBJECTS) $(DAP4MarshallerTest_LDADD) $(LIBS)
-DAP4UnMarshallerTest$(EXEEXT): $(DAP4UnMarshallerTest_OBJECTS) $(DAP4UnMarshallerTest_DEPENDENCIES) $(EXTRA_DAP4UnMarshallerTest_DEPENDENCIES) 
-	@rm -f DAP4UnMarshallerTest$(EXEEXT)
-	$(CXXLINK) $(DAP4UnMarshallerTest_OBJECTS) $(DAP4UnMarshallerTest_LDADD) $(LIBS)
+D4EnumTest$(EXEEXT): $(D4EnumTest_OBJECTS) $(D4EnumTest_DEPENDENCIES) $(EXTRA_D4EnumTest_DEPENDENCIES) 
+	@rm -f D4EnumTest$(EXEEXT)
+	$(CXXLINK) $(D4EnumTest_OBJECTS) $(D4EnumTest_LDADD) $(LIBS)
+D4GroupTest$(EXEEXT): $(D4GroupTest_OBJECTS) $(D4GroupTest_DEPENDENCIES) $(EXTRA_D4GroupTest_DEPENDENCIES) 
+	@rm -f D4GroupTest$(EXEEXT)
+	$(CXXLINK) $(D4GroupTest_OBJECTS) $(D4GroupTest_LDADD) $(LIBS)
+D4MarshallerTest$(EXEEXT): $(D4MarshallerTest_OBJECTS) $(D4MarshallerTest_DEPENDENCIES) $(EXTRA_D4MarshallerTest_DEPENDENCIES) 
+	@rm -f D4MarshallerTest$(EXEEXT)
+	$(CXXLINK) $(D4MarshallerTest_OBJECTS) $(D4MarshallerTest_LDADD) $(LIBS)
+D4ParserSax2Test$(EXEEXT): $(D4ParserSax2Test_OBJECTS) $(D4ParserSax2Test_DEPENDENCIES) $(EXTRA_D4ParserSax2Test_DEPENDENCIES) 
+	@rm -f D4ParserSax2Test$(EXEEXT)
+	$(CXXLINK) $(D4ParserSax2Test_OBJECTS) $(D4ParserSax2Test_LDADD) $(LIBS)
+D4UnMarshallerTest$(EXEEXT): $(D4UnMarshallerTest_OBJECTS) $(D4UnMarshallerTest_DEPENDENCIES) $(EXTRA_D4UnMarshallerTest_DEPENDENCIES) 
+	@rm -f D4UnMarshallerTest$(EXEEXT)
+	$(CXXLINK) $(D4UnMarshallerTest_OBJECTS) $(D4UnMarshallerTest_LDADD) $(LIBS)
 DASTest$(EXEEXT): $(DASTest_OBJECTS) $(DASTest_DEPENDENCIES) $(EXTRA_DASTest_DEPENDENCIES) 
 	@rm -f DASTest$(EXEEXT)
 	$(CXXLINK) $(DASTest_OBJECTS) $(DASTest_LDADD) $(LIBS)
@@ -1084,6 +1191,9 @@ DDSTest$(EXEEXT): $(DDSTest_OBJECTS) $(DDSTest_DEPENDENCIES) $(EXTRA_DDSTest_DEP
 DDXParserTest$(EXEEXT): $(DDXParserTest_OBJECTS) $(DDXParserTest_DEPENDENCIES) $(EXTRA_DDXParserTest_DEPENDENCIES) 
 	@rm -f DDXParserTest$(EXEEXT)
 	$(CXXLINK) $(DDXParserTest_OBJECTS) $(DDXParserTest_LDADD) $(LIBS)
+DMRTest$(EXEEXT): $(DMRTest_OBJECTS) $(DMRTest_DEPENDENCIES) $(EXTRA_DMRTest_DEPENDENCIES) 
+	@rm -f DMRTest$(EXEEXT)
+	$(CXXLINK) $(DMRTest_OBJECTS) $(DMRTest_LDADD) $(LIBS)
 HTTPCacheTest$(EXEEXT): $(HTTPCacheTest_OBJECTS) $(HTTPCacheTest_DEPENDENCIES) $(EXTRA_HTTPCacheTest_DEPENDENCIES) 
 	@rm -f HTTPCacheTest$(EXEEXT)
 	$(CXXLINK) $(HTTPCacheTest_OBJECTS) $(HTTPCacheTest_LDADD) $(LIBS)
@@ -1120,6 +1230,9 @@ arrayT$(EXEEXT): $(arrayT_OBJECTS) $(arrayT_DEPENDENCIES) $(EXTRA_arrayT_DEPENDE
 attrTableT$(EXEEXT): $(attrTableT_OBJECTS) $(attrTableT_DEPENDENCIES) $(EXTRA_attrTableT_DEPENDENCIES) 
 	@rm -f attrTableT$(EXEEXT)
 	$(CXXLINK) $(attrTableT_OBJECTS) $(attrTableT_LDADD) $(LIBS)
+chunked_iostream_test$(EXEEXT): $(chunked_iostream_test_OBJECTS) $(chunked_iostream_test_DEPENDENCIES) $(EXTRA_chunked_iostream_test_DEPENDENCIES) 
+	@rm -f chunked_iostream_test$(EXEEXT)
+	$(CXXLINK) $(chunked_iostream_test_OBJECTS) $(chunked_iostream_test_LDADD) $(LIBS)
 dasT$(EXEEXT): $(dasT_OBJECTS) $(dasT_DEPENDENCIES) $(EXTRA_dasT_DEPENDENCIES) 
 	@rm -f dasT$(EXEEXT)
 	$(CXXLINK) $(dasT_OBJECTS) $(dasT_LDADD) $(LIBS)
@@ -1151,13 +1264,19 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ArrayTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/AttrTableTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ByteTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4AsyncDocTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4AttributesTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4DimensionsTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4EnumDefsTest.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DAP4MarshallerTest.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DAP4UnMarshallerTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4EnumTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4GroupTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4MarshallerTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4ParserSax2Test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/D4UnMarshallerTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DASTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DDSTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DDXParserTest-DDXParserTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DMRTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/HTTPCacheTest-HTTPCacheTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/HTTPConnectTest-HTTPConnectTest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MIMEUtilTest.Po at am__quote@
@@ -1170,6 +1289,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ancT.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/arrayT.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/attrTableT.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/chunked_iostream_test.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dasT.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ddsT.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/generalUtilTest.Po at am__quote@
@@ -1684,6 +1804,9 @@ uninstall-am:
 test_config.h: test_config.h.in Makefile
 	sed -e "s%[@]abs_srcdir[@]%${abs_srcdir}%" $< > test_config.h
 
+D4-xml.tar.gz: D4-xml/DMR_*[0-9].xml
+	tar -czf $@ $^
+
 @CPPUNIT_FALSE at check-local:
 @CPPUNIT_FALSE@	@echo ""
 @CPPUNIT_FALSE@	@echo "**********************************************************"
diff --git a/unit-tests/MarshallerTest.cc b/unit-tests/MarshallerTest.cc
index f850d11..5531834 100644
--- a/unit-tests/MarshallerTest.cc
+++ b/unit-tests/MarshallerTest.cc
@@ -176,33 +176,21 @@ public:
 
     void tearDown()
     {
-        delete b;
-        b = 0;
-        delete i16;
-        i16 = 0;
-        delete i32;
-        i32 = 0;
-        delete ui16;
-        ui16 = 0;
-        delete ui32;
-        ui32 = 0;
-        delete f32;
-        f32 = 0;
-        delete f64;
-        f64 = 0;
-        delete str;
-        str = 0;
-        delete url;
-        url = 0;
-
-        delete ab;
-        ab = 0;
-
-        delete arr;
-        arr = 0;
-
-        delete s;
-        s = 0;
+        delete b; b = 0;
+        delete i16; i16 = 0;
+        delete i32; i32 = 0;
+        delete ui16; ui16 = 0;
+        delete ui32; ui32 = 0;
+        delete f32; f32 = 0;
+        delete f64; f64 = 0;
+        delete str; str = 0;
+        delete url; url = 0;
+
+        delete ab;  ab = 0;
+
+        delete arr; arr = 0;
+        delete db; db = 0;
+        delete s; s = 0;
     }
 
     void simple_types_file_serialize_test()
diff --git a/unit-tests/RCReaderTest.cc b/unit-tests/RCReaderTest.cc
index 1a66c76..6433212 100644
--- a/unit-tests/RCReaderTest.cc
+++ b/unit-tests/RCReaderTest.cc
@@ -22,7 +22,7 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //
 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
- 
+
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -51,6 +51,14 @@
 using namespace CppUnit;
 using namespace std;
 
+#include"GetOpt.h"
+
+static bool debug = false;
+static char dods_conf_ev[1024] = "";
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
 namespace libdap
 {
 
@@ -67,6 +75,19 @@ public:
 
     void tearDown() {}
 
+    /** Put values in an environment variable. This should be used only
+     * for the env var 'DODS_CONF' and should never pass in values longer
+     * than 1024 characters. The 'value' must include the DODS_CONF= text.
+     *
+     * @note this is used because environment variables use static storage,
+     * so any value passed in from the heap that might be freed or from the
+     * stack that could be popped will cause a memory access error.
+     */
+    void my_putenv(const string &value) {
+        strncpy(dods_conf_ev, value.c_str(), 1024);;
+        putenv(dods_conf_ev);
+    }
+
     CPPUNIT_TEST_SUITE(RCReaderTest);
 
     CPPUNIT_TEST(check_env_var_test1);
@@ -82,264 +103,264 @@ public:
     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") == "");
+        my_putenv("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") == "");
+        my_putenv("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");
+        my_putenv("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());
+        // 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
+
+        my_putenv(string("DODS_CONF=") + string(cwd));
+
+        // 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());
+        // 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);
+
+        my_putenv(string("DODS_CONF=") + string(cwd));
+
+        // Create the file.
+        string rc = string(cwd) + string("/.dodsrc");
+        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/"));
+        // This test assumes that HOME *is* defined. We should find the
+        // .dodsrc there. If it's not there, we should create one there.
+        my_putenv("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/"));
-	
+        // 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
+
+        my_putenv(string("DODS_CONF=") + string(cwd));
+
+        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");
+        string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test1.rc" ;
+        DBG(cerr << "rc: " << rc << endl);
+        my_putenv(rc);
+
+        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() == "");
+        string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test2.rc" ;
+        DBG(cerr << "rc: " << rc << endl);
+        my_putenv(rc);
+
+        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() != "");
-	}
+        string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test3.rc" ;
+        DBG(cerr << "rc: " << rc << endl);
+        my_putenv(rc);
+
+        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() != "");
-	}
+        string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test4.rc" ;
+        DBG(cerr << "rc: " << rc << endl);
+        my_putenv(rc);
+
+        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() != "");
-	}
+        string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test5.rc" ;
+        DBG(cerr << "rc: " << rc << endl);
+        my_putenv(rc);
+
+        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());
+        string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/dodssrc_ssl_1" ;
+        DBG(cerr << "rc: " << rc << endl);
+        my_putenv(rc);
 
         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);
+                << 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());
+        // Note that string rc, rc2, and rc3 are used (instead of reusing one
+        // string object) because the code casts away the const-ness of the
+        // char* returned by c_str() and putenv does odd stuff with it. There's
+        // nothing good about using env vars...
+        rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/dodssrc_ssl_2" ;
+        DBG(cerr << "rc: " << rc << endl);
+
+        my_putenv(rc);
 
         RCReader::delete_instance();
         RCReader::initialize_instance();
         reader = RCReader::instance();
         DBG(cerr << "reader->check_env_var(\"DODS_CONF\"): " 
-            << reader->check_env_var("DODS_CONF") << endl);
+                << reader->check_env_var("DODS_CONF") << endl);
         DBG(cerr << "reader->get_validate_ssl(): " << reader->get_validate_ssl()
-            << endl);
+                << 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());
+        rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/dodsrc_ssl_3" ;
+        DBG(cerr << "rc: " << rc << endl);
+
+        my_putenv(rc);
 
         RCReader::delete_instance();
         RCReader::initialize_instance();
         reader = RCReader::instance();
         DBG(cerr << "reader->get_validate_ssl(): " << reader->get_validate_ssl()
-            << endl);
+                << endl);
         CPPUNIT_ASSERT(reader->get_validate_ssl() == 0);
     }
 };
@@ -348,13 +369,36 @@ CPPUNIT_TEST_SUITE_REGISTRATION(RCReaderTest);
 
 } // namespace libdap
 
-int 
-main( int, char** )
-{
+int main(int argc, char*argv[]) {
     CppUnit::TextTestRunner runner;
-    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+            case 'd':
+                debug = 1;  // debug is a static global
+                break;
+            default:
+                break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::RCReaderTest::") + argv[i++];
 
-    bool wasSuccessful = runner.run( "", false ) ;
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
 
     return wasSuccessful ? 0 : 1;
 }
diff --git a/unit-tests/SequenceTest.cc b/unit-tests/SequenceTest.cc
index 98a3da1..ed4d3fc 100644
--- a/unit-tests/SequenceTest.cc
+++ b/unit-tests/SequenceTest.cc
@@ -11,18 +11,18 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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>
@@ -41,8 +41,14 @@
 #include "../tests/TestStr.h"
 
 #include "GNURegex.h"
+#include "GetOpt.h"
 #include "debug.h"
 
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
 using namespace CppUnit;
 using namespace std;
 
@@ -51,14 +57,14 @@ 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\
+        "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_parent: 0.*\n\
           d_attr: 0x.*\n\
 BaseType \\(0x.*\\):\n\
           _name: i1\n\
@@ -103,63 +109,56 @@ 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);        
+    void setUp() {
+        // Set up a simple sequence. Used to test ctor, assigment, et cetera.
+        s = new TestSequence("s");
+        s->add_var_nocopy(new TestInt32("i1"));
+        s->add_var_nocopy(new TestStr("str1"));
+        s->add_var_nocopy(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->add_var_nocopy(new TestInt32("i1"));
         ss->set_series_values(true);
-        
+
         ps = new TestSequence("child_of_ss");
-        ps->add_var(new TestInt32("i2"));
+        ps->add_var_nocopy(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.
+
+        ss->add_var_nocopy(ps);
+
+        // Set up sss, used to test multi-level sequences
+        sss = new TestSequence("sss");
+        sss->add_var_nocopy(new TestInt32("i1"));
+
+        ts = new TestSequence("child_of_sss");
+        ts->add_var_nocopy(new TestStr("str1"));
+
+        tts = new TestSequence("child_of_child_of_sss");
+        tts->add_var_nocopy(new TestInt32("i2"));
+        ts->add_var_nocopy(tts);
+
+        sss->add_var_nocopy(ts);	// This has to be here because add_var_nocopy 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;
-        
+        dds->add_var_nocopy(s);
+        dds->add_var_nocopy(ss);
+        dds->add_var_nocopy(sss);
+    }
+
+    void tearDown() {
         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);
+        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 );
@@ -179,6 +178,7 @@ public:
 
     CPPUNIT_TEST_SUITE_END();
 
+#if 0
     // Tests for methods
     void intern_data_test1() {
         ConstraintEvaluator ce;
@@ -186,7 +186,7 @@ public:
         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);
@@ -203,7 +203,7 @@ public:
             CPPUNIT_ASSERT(!"Error in transfer_data_for_leaf_test1()");
         }
     }
-    
+
     void intern_data_test2() {
         ConstraintEvaluator ce;
         ss->set_send_p(true);
@@ -211,7 +211,7 @@ public:
         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);
@@ -221,7 +221,7 @@ public:
             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);
@@ -233,7 +233,7 @@ public:
             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);
@@ -250,7 +250,7 @@ public:
             CPPUNIT_ASSERT(!"Error in transfer_data_test2()");
         }
     }
-    
+
     void intern_data_test3() {
         ConstraintEvaluator ce;
         sss->set_send_p(true);
@@ -267,14 +267,14 @@ public:
             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);
@@ -283,12 +283,12 @@ public:
             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);
@@ -303,7 +303,7 @@ public:
             CPPUNIT_ASSERT(!"Error in transfer_data_test3()");
         }
     }
-    
+
     void intern_data_for_leaf_test() {
         ConstraintEvaluator ce;
         s->set_send_p(true);
@@ -311,7 +311,7 @@ public:
             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);
@@ -328,18 +328,18 @@ public:
             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->add_var_nocopy(ss);
         sss->set_send_p(true);
         try {
-             sss->set_leaf_sequence(1);
-             CPPUNIT_ASSERT(!"Should have thrown Error");
+            sss->set_leaf_sequence(1);
+            CPPUNIT_ASSERT(!"Should have thrown Error");
         }
         catch (Error &e) {
-             cerr << e.get_error_message() << endl;
-             CPPUNIT_ASSERT("Caught Error");
+            cerr << e.get_error_message() << endl;
+            CPPUNIT_ASSERT("Caught Error");
         }
     }
 
@@ -356,7 +356,7 @@ public:
         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());
@@ -371,21 +371,21 @@ public:
         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.
+        // add_var_nocopy() _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());
@@ -394,21 +394,22 @@ public:
         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()));
-    }
+#endif
 
     void assignment() {
-	Sequence ts2 = *s;
-	DBG(cerr << "ts2: " << ts2.toString() << endl);
-	CPPUNIT_ASSERT(re_match(s_regex, ts2.toString().c_str()));
+        Sequence ts2 = *s;
+        DBG(cerr << "ts2: " << ts2.toString() << endl);
+        CPPUNIT_ASSERT(re_match(s_regex, ts2.toString().c_str()));
     }
 
+    void ctor_test() {
+		DBG(cerr << "s: " << s->toString() << endl);
+		CPPUNIT_ASSERT(re_match(s_regex, s->toString().c_str()));
+	}
+
     void copy_ctor() {
-	Sequence s2 = *s;
-	CPPUNIT_ASSERT(re_match(s_regex, s2.toString().c_str()));
+        Sequence s2 = *s;
+        CPPUNIT_ASSERT(re_match(s_regex, s2.toString().c_str()));
     }
 };
 
@@ -416,13 +417,35 @@ CPPUNIT_TEST_SUITE_REGISTRATION(SequenceTest);
 
 }
 
-int 
-main( int, char** )
-{
+int main(int argc, char*argv[]) {
     CppUnit::TextTestRunner runner;
-    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    GetOpt getopt(argc, argv, "d");
+    int option_char;
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = 1;  // debug is a static global
+            break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::SequenceTest::") + argv[i++];
 
-    bool wasSuccessful = runner.run( "", false ) ;
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
 
     return wasSuccessful ? 0 : 1;
 }
diff --git a/unit-tests/ServerFunctionsListUnitTest.cc b/unit-tests/ServerFunctionsListUnitTest.cc
index f4a6c96..0278b8f 100644
--- a/unit-tests/ServerFunctionsListUnitTest.cc
+++ b/unit-tests/ServerFunctionsListUnitTest.cc
@@ -46,7 +46,7 @@ static bool debug = false;
 #define DBG(x) do { if (debug) (x); } while(false);
 
 
-void sflut(int argc, libdap::BaseType *argv[], libdap::DDS &dds, libdap::BaseType **btpp)
+void sflut(int, libdap::BaseType *[], libdap::DDS &, libdap::BaseType **btpp)
 {
     string info = string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
             + "<function name=\"ugr4\" version=\"0.1\">\n"
@@ -122,7 +122,7 @@ public:
             return;
         }
 
-        for(int i=0; i<names->size() ;i++){
+        for(size_t i=0; i<names->size() ;i++){
             DBG(cerr <<  "   name["<< i << "]: "<< (*names)[i] << endl);
         }
     }
@@ -183,7 +183,7 @@ int main(int argc, char*argv[]) {
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
 
     GetOpt getopt(argc, argv, "d");
-    char option_char;
+    int option_char;
     while ((option_char = getopt()) != EOF)
         switch (option_char) {
         case 'd':
diff --git a/unit-tests/SignalHandlerTest.cc b/unit-tests/SignalHandlerTest.cc
index 3679ba6..b2ddcef 100644
--- a/unit-tests/SignalHandlerTest.cc
+++ b/unit-tests/SignalHandlerTest.cc
@@ -1,3 +1,4 @@
+
 // -*- mode: c++; c-basic-offset:4 -*-
 
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
@@ -10,12 +11,12 @@
 // 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
@@ -34,86 +35,130 @@
 #include <process.h>
 #endif
 
+#include "GetOpt.h"
 #include "SignalHandler.h"
 #include "debug.h"
 
 using namespace CppUnit;
 using namespace std;
 
-namespace libdap {
+static bool debug = false;
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
 
-class SignalHandlerTest: public TestFixture {
+namespace libdap
+{
+
+/** 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) {
+        DBG(cerr << "signal number " << signum << " received" << endl);
+        flag = 1;
+    }
+};
+
+class SignalHandlerTest : public TestFixture {
 private:
-	SignalHandler *sh;
-	TestHandler *th;
+    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()
-	;
+    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()
+    {
+        sh->register_handler(SIGALRM, th);
+        CPPUNIT_ASSERT(sh->remove_handler(SIGALRM) == th);
+    }
+
+    void alarm_test()
+    {
+        sh->register_handler(SIGALRM, th, true);
+        CPPUNIT_ASSERT(th->flag == 0);
+        alarm(1);
+
+        // sleep(2) also works _except_ when run with valgrind; reason
+        // unknown. jhrg 4/26/13
+        int start, end;
+        start = end = time(0);
+        while (end < start + 2)
+            end = time(0);
+
+        DBG(cerr << "Event handler 'flag' value: " << th->flag << endl);
+        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;
+int main(int argc, char*argv[]) {
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            debug = 1;  // debug is a static global
+            break;
+        default:
+            break;
+        }
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("libdap::SignalHandlerTest::") + argv[i++];
+            DBG(cerr << "Running " << test << endl);
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
+    return wasSuccessful ? 0 : 1;
 }
 
diff --git a/unit-tests/arrayT.cc b/unit-tests/arrayT.cc
index 2e07526..a18d763 100644
--- a/unit-tests/arrayT.cc
+++ b/unit-tests/arrayT.cc
@@ -10,8 +10,9 @@
 #include "TestArray.h"
 #include "TestInt16.h"
 #include "TestTypeFactory.h"
+
 #include "util.h"
-//#include "Pix.h"
+#include "debug.h"
 
 using std::cerr ;
 using std::endl ;
@@ -52,9 +53,9 @@ public:
 	try
 	{
 	    int w = ar.width(true) ;
-	    cerr << "w = " << w << endl;
-	    cerr << "(int)bt->width() " << (int)bt->width() << endl;
-	    cerr << "L " << l << endl;
+	    DBG(cerr << "w = " << w << endl);
+	    DBG(cerr << "(int)bt->width() " << (int)bt->width() << endl);
+	    DBG(cerr << "L " << l << endl);
 	    CPPUNIT_ASSERT( w == ( l * (int)bt->width() ) ) ;
 	}
 	catch( InternalErr &e )
diff --git a/unit-tests/cache-testsuite/Makefile.in b/unit-tests/cache-testsuite/Makefile.in
index 9d07d73..bd60d6d 100644
--- a/unit-tests/cache-testsuite/Makefile.in
+++ b/unit-tests/cache-testsuite/Makefile.in
@@ -57,19 +57,23 @@ 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/byteswap.m4 $(top_srcdir)/gl/m4/codeset.m4 \
 	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/eealloc.m4 \
 	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/extern-inline.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/lib-ld.m4 $(top_srcdir)/gl/m4/lib-link.m4 \
+	$(top_srcdir)/gl/m4/lib-prefix.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/locale_h.m4 \
-	$(top_srcdir)/gl/m4/localeconv.m4 \
+	$(top_srcdir)/gl/m4/localeconv.m4 $(top_srcdir)/gl/m4/lock.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/mbtowc.m4 \
@@ -78,17 +82,18 @@ am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
 	$(top_srcdir)/gl/m4/off_t.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/strcase.m4 \
-	$(top_srcdir)/gl/m4/strings_h.m4 \
+	$(top_srcdir)/gl/m4/stdlib_h.m4 \
 	$(top_srcdir)/gl/m4/sys_types_h.m4 \
+	$(top_srcdir)/gl/m4/threadlib.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/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/cppunit.m4 \
+	$(top_srcdir)/conf/gcov_valgrind.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) \
@@ -160,7 +165,6 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
-EVAL = @EVAL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GLIBC21 = @GLIBC21@
@@ -181,7 +185,6 @@ GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
 GNULIB_FCHDIR = @GNULIB_FCHDIR@
 GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
 GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
-GNULIB_FFS = @GNULIB_FFS@
 GNULIB_FSYNC = @GNULIB_FSYNC@
 GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
 GNULIB_GETCWD = @GNULIB_GETCWD@
@@ -235,6 +238,7 @@ GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
 GNULIB_REALPATH = @GNULIB_REALPATH@
 GNULIB_RMDIR = @GNULIB_RMDIR@
 GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
 GNULIB_SETENV = @GNULIB_SETENV@
 GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
 GNULIB_SETLOCALE = @GNULIB_SETLOCALE@
@@ -307,7 +311,6 @@ HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
 HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
 HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
 HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
-HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
 HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
 HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
 HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
@@ -321,7 +324,6 @@ HAVE_FCHDIR = @HAVE_FCHDIR@
 HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
 HAVE_FDATASYNC = @HAVE_FDATASYNC@
 HAVE_FEATURES_H = @HAVE_FEATURES_H@
-HAVE_FFS = @HAVE_FFS@
 HAVE_FSYNC = @HAVE_FSYNC@
 HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
 HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
@@ -370,6 +372,7 @@ HAVE_READLINK = @HAVE_READLINK@
 HAVE_READLINKAT = @HAVE_READLINKAT@
 HAVE_REALPATH = @HAVE_REALPATH@
 HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
 HAVE_SETENV = @HAVE_SETENV@
 HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
 HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
@@ -377,8 +380,6 @@ 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_STRCASECMP = @HAVE_STRCASECMP@
-HAVE_STRINGS_H = @HAVE_STRINGS_H@
 HAVE_STRTOD = @HAVE_STRTOD@
 HAVE_STRTOLL = @HAVE_STRTOLL@
 HAVE_STRTOULL = @HAVE_STRTOULL@
@@ -395,6 +396,7 @@ HAVE_UNLINKAT = @HAVE_UNLINKAT@
 HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
 HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
 HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_VALGRIND = @HAVE_VALGRIND@
 HAVE_WCHAR_H = @HAVE_WCHAR_H@
 HAVE_WCHAR_T = @HAVE_WCHAR_T@
 HAVE_WCPCPY = @HAVE_WCPCPY@
@@ -449,8 +451,12 @@ LEXLIB = @LEXLIB@
 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
 LIBDAP_VERSION = @LIBDAP_VERSION@
 LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
 LIBS = @LIBS@
+LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -460,7 +466,10 @@ LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
 LOCALE_JA = @LOCALE_JA@
 LOCALE_ZH_CN = @LOCALE_ZH_CN@
 LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -469,7 +478,6 @@ NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_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_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
 NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_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@
@@ -479,7 +487,6 @@ NEXT_LOCALE_H = @NEXT_LOCALE_H@
 NEXT_STDDEF_H = @NEXT_STDDEF_H@
 NEXT_STDINT_H = @NEXT_STDINT_H@
 NEXT_STDLIB_H = @NEXT_STDLIB_H@
-NEXT_STRINGS_H = @NEXT_STRINGS_H@
 NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
 NEXT_UNISTD_H = @NEXT_UNISTD_H@
 NEXT_WCHAR_H = @NEXT_WCHAR_H@
@@ -519,6 +526,7 @@ REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
 REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
 REPLACE_GETCWD = @REPLACE_GETCWD@
 REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
 REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
 REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
 REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
@@ -542,6 +550,7 @@ REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
 REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
 REPLACE_NULL = @REPLACE_NULL@
 REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
 REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
 REPLACE_PUTENV = @REPLACE_PUTENV@
 REPLACE_PWRITE = @REPLACE_PWRITE@
@@ -647,6 +656,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -672,9 +682,9 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu unit-tests/cache-testsuite/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign unit-tests/cache-testsuite/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu unit-tests/cache-testsuite/Makefile
+	  $(AUTOMAKE) --foreign unit-tests/cache-testsuite/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
diff --git a/unit-tests/cgi-util-tests/multipart_mime_header1.txt b/unit-tests/cgi-util-tests/multipart_mime_header1.txt
index 20141a3..53d65c1 100644
--- a/unit-tests/cgi-util-tests/multipart_mime_header1.txt
+++ b/unit-tests/cgi-util-tests/multipart_mime_header1.txt
@@ -1,6 +1,6 @@
 --my_boundary
 Content-Type: Text/xml; charset=iso-8859-1
-Content-Description: dap4-ddx
+Content-Description: dods-ddx
 Content-Id: <1234 at opendap.org>
 
 <?xml version="1.0">
diff --git a/unit-tests/chunked-io/test_big_binary_file.bin b/unit-tests/chunked-io/test_big_binary_file.bin
new file mode 100644
index 0000000..49c7ebb
Binary files /dev/null and b/unit-tests/chunked-io/test_big_binary_file.bin differ
diff --git a/unit-tests/chunked-io/test_big_binary_file.bin.chunked b/unit-tests/chunked-io/test_big_binary_file.bin.chunked
new file mode 100644
index 0000000..c88ce78
Binary files /dev/null and b/unit-tests/chunked-io/test_big_binary_file.bin.chunked differ
diff --git a/unit-tests/chunked-io/test_big_binary_file.bin.plain b/unit-tests/chunked-io/test_big_binary_file.bin.plain
new file mode 100644
index 0000000..49c7ebb
Binary files /dev/null and b/unit-tests/chunked-io/test_big_binary_file.bin.plain differ
diff --git a/unit-tests/chunked-io/test_big_binary_file_2.bin b/unit-tests/chunked-io/test_big_binary_file_2.bin
new file mode 100644
index 0000000..adc3d8b
Binary files /dev/null and b/unit-tests/chunked-io/test_big_binary_file_2.bin differ
diff --git a/unit-tests/chunked-io/test_big_binary_file_2.bin.chunked b/unit-tests/chunked-io/test_big_binary_file_2.bin.chunked
new file mode 100644
index 0000000..918b688
Binary files /dev/null and b/unit-tests/chunked-io/test_big_binary_file_2.bin.chunked differ
diff --git a/unit-tests/chunked-io/test_big_binary_file_2.bin.plain b/unit-tests/chunked-io/test_big_binary_file_2.bin.plain
new file mode 100644
index 0000000..b69a86d
Binary files /dev/null and b/unit-tests/chunked-io/test_big_binary_file_2.bin.plain differ
diff --git a/unit-tests/chunked-io/test_big_binary_file_3.bin b/unit-tests/chunked-io/test_big_binary_file_3.bin
new file mode 100644
index 0000000..bfcb051
Binary files /dev/null and b/unit-tests/chunked-io/test_big_binary_file_3.bin differ
diff --git a/unit-tests/chunked-io/test_small_text_file.txt b/unit-tests/chunked-io/test_small_text_file.txt
new file mode 100644
index 0000000..07efa5a
--- /dev/null
+++ b/unit-tests/chunked-io/test_small_text_file.txt
@@ -0,0 +1 @@
+This is a small file
diff --git a/unit-tests/chunked-io/test_small_text_file.txt.chunked b/unit-tests/chunked-io/test_small_text_file.txt.chunked
new file mode 100644
index 0000000..98f9637
Binary files /dev/null and b/unit-tests/chunked-io/test_small_text_file.txt.chunked differ
diff --git a/unit-tests/chunked-io/test_small_text_file.txt.plain b/unit-tests/chunked-io/test_small_text_file.txt.plain
new file mode 100644
index 0000000..07efa5a
--- /dev/null
+++ b/unit-tests/chunked-io/test_small_text_file.txt.plain
@@ -0,0 +1 @@
+This is a small file
diff --git a/unit-tests/chunked-io/test_text_file.txt b/unit-tests/chunked-io/test_text_file.txt
new file mode 100644
index 0000000..9a6ac95
--- /dev/null
+++ b/unit-tests/chunked-io/test_text_file.txt
@@ -0,0 +1,370 @@
+
+// -*- 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.
+
+// Tests for the AISMerge class.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+//#define DODS_DEBUG
+
+#include "Connect.h"
+#include "AISMerge.h"
+#include "debug.h"
+#include <test_config.h>
+
+#include "testFile.h"
+
+using namespace CppUnit;
+
+namespace libdap
+{
+
+class AISMergeTest:public TestFixture {
+  private:
+    AISMerge * ais_merge;
+
+    static string fnoc1, fnoc2, fnoc3, bears, coads, three_fnoc;
+    static string fnoc1_ais, fnoc2_ais, digit_ais, fnoc3_das;
+
+    static string fnoc1_ais_string, bears_1_ais_string, coads_ais_string;
+    static string fnoc1_merge_ais, fnoc2_merge_ais, fnoc3_merge_ais;
+    static string three_fnoc_merge_ais, starts_with_number_ais_string;
+
+    string dump2string(FILE * res) {
+        string stuff = "";
+        char line[256];
+        while (!feof(res) && !ferror(res)
+               && fgets(&line[0], 256, res) != 0)
+             stuff += line;
+
+         return stuff;
+  } public:
+     AISMergeTest() {
+    }
+    ~AISMergeTest() {
+    }
+
+    void setUp() {
+        ais_merge = new AISMerge("ais_testsuite/ais_database.xml");
+    }
+
+    void tearDown() {
+        delete ais_merge;
+        ais_merge = 0;
+    }
+
+    CPPUNIT_TEST_SUITE(AISMergeTest);
+
+    CPPUNIT_TEST(get_ais_resource_test);
+    CPPUNIT_TEST(merge_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void get_ais_resource_test() {
+        try {
+            ResourceVector rv = ais_merge->d_ais_db.get_resource(fnoc1);
+            Response *res = ais_merge->get_ais_resource(rv[0].get_url());
+            string stuff = dump2string(res->get_stream());
+            DBG(cerr << "AIS Resource: " << stuff << endl);
+            CPPUNIT_ASSERT(stuff.find(fnoc1_ais_string)
+                           != string::npos);
+
+            rv = ais_merge->d_ais_db.get_resource(coads);
+            res = ais_merge->get_ais_resource(rv[0].get_url());
+            CPPUNIT_ASSERT(dump2string(res->get_stream()).
+                           find(coads_ais_string)
+                           != string::npos);
+
+            rv = ais_merge->d_ais_db.get_resource(three_fnoc);
+            res = ais_merge->get_ais_resource(rv[0].get_url());
+            CPPUNIT_ASSERT(dump2string(res->get_stream()).
+                           find(starts_with_number_ais_string)
+                           != string::npos);
+        }
+        catch(Error & e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            // If the exception is Not Found then this is not an error; there
+            // are many reasons why the resource might not be found...
+            if (e.get_error_message().find("Not Found:") == string::npos)
+                CPPUNIT_ASSERT(!"Error");
+        }
+    }
+
+    void merge_test() {
+        try {
+            Connect *conn;
+            DAS das;
+            string sof;
+
+            conn = new Connect(fnoc1);  // test overwrite (default)
+            conn->request_das(das);
+            ais_merge->merge(fnoc1, das);
+            FILE2string(sof, of, das.print(of));
+            DBG(cerr << "Merged fnoc1 DAS: " << sof << endl);
+            CPPUNIT_ASSERT(sof.find(fnoc1_merge_ais) != string::npos);
+
+            delete conn;
+            conn = 0;
+            das.erase();
+
+            conn = new Connect(fnoc2);  // test replace
+            conn->request_das(das);
+            ais_merge->merge(fnoc2, das);
+            FILE2string(sof, of, das.print(of));
+            CPPUNIT_ASSERT(sof.find(fnoc2_merge_ais) != string::npos);
+
+            delete conn;
+            conn = 0;
+            das.erase();
+
+            conn = new Connect(fnoc3);  // test fallback
+            conn->request_das(das);     // with a non-empty das, nothing happens
+            ais_merge->merge(fnoc3, das);
+            FILE2string(sof, of, das.print(of));
+            CPPUNIT_ASSERT(sof.find(fnoc3_das) != string::npos);
+
+            das.erase();        // empty das, should add attributes
+            ais_merge->merge(fnoc3, das);
+            FILE2string(sof, of, das.print(of));
+            CPPUNIT_ASSERT(sof.find(fnoc3_merge_ais) != string::npos);
+
+            conn = new Connect(three_fnoc);     // test regexp
+            conn->request_das(das);     // with a non-empty das, nothing happens
+            ais_merge->merge(three_fnoc, das);
+            FILE2string(sof, of, das.print(of));
+            CPPUNIT_ASSERT(sof.find(three_fnoc_merge_ais)
+                           != string::npos);
+        }
+        catch(Error & e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            if (e.get_error_message().find("Not Found:") == string::npos)
+                CPPUNIT_ASSERT(!"Error");
+        }
+    }
+};
+
+string AISMergeTest::fnoc1 =
+    "http://test.opendap.org/opendap/data/nc/fnoc1.nc";
+string AISMergeTest::fnoc2 =
+    "http://test.opendap.org/opendap/data/nc/fnoc2.nc";
+string AISMergeTest::fnoc3 =
+    "http://test.opendap.org/opendap/data/nc/fnoc3.nc";
+string AISMergeTest::bears =
+    "http://test.opendap.org/opendap/data/nc/bears.nc";
+string AISMergeTest::coads =
+    "http://test.opendap.org/opendap/data/nc/coads_climatology.nc";
+string AISMergeTest::three_fnoc =
+    "http://test.opendap.org/opendap/data/nc/3fnoc.nc";
+
+string AISMergeTest::fnoc1_ais =
+    "http://test.opendap.org/ais/fnoc1.nc.das";
+string AISMergeTest::fnoc2_ais =
+    "http://test.opendap.org/ais/fnoc2.nc.das";
+string AISMergeTest::digit_ais = (string)TEST_SRC_DIR + "/ais_testsuite/starts_with_number.das";
+
+string AISMergeTest::fnoc1_ais_string = "Attributes {\n\
+    u {\n\
+	String DODS_Name \"UWind\";\n\
+    }\n\
+    v {\n\
+	String DODS_Name \"VWind\";\n\
+    }\n\
+}";
+
+string AISMergeTest::bears_1_ais_string = "Attributes {\n\
+    bears {\n\
+	String longname \"Test data\";\n\
+    }\n\
+}";
+
+string AISMergeTest::coads_ais_string = "Attributes {\n\
+    COADSX {\n\
+        String long_name \"Longitude\";\n\
+    }\n\
+}";
+
+string AISMergeTest::starts_with_number_ais_string = "Attributes {\n\
+    NC_GLOBAL {\n\
+        String AIS_Test_info \"This dataset's name starts with a digit.\";\n\
+    }\n\
+}";
+
+string AISMergeTest::fnoc3_das = "Attributes {\n\
+    u {\n\
+        String units \"meter per second\";\n\
+        String long_name \"Vector wind eastward component\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+    }\n\
+    v {\n\
+        String units \"meter per second\";\n\
+        String long_name \"Vector wind northward component\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+    }\n\
+    lat {\n\
+        String units \"degree North\";\n\
+    }\n\
+    lon {\n\
+        String units \"degree East\";\n\
+    }\n\
+    time {\n\
+        String units \"hours from base_time\";\n\
+    }\n\
+    NC_GLOBAL {\n\
+        String base_time \"88-245-00:00:00\";\n\
+        String title \" FNOC UV wind components from 1988-245 to 1988-247.\";\n\
+    }\n\
+    DODS_EXTRA {\n\
+        String Unlimited_Dimension \"time_a\";\n\
+    }\n\
+}";
+
+string AISMergeTest::fnoc1_merge_ais = "Attributes {\n\
+    u {\n\
+        String units \"meter per second\";\n\
+        String long_name \"Vector wind eastward component\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+        String DODS_Name \"UWind\", \"UWind\";\n\
+        Byte b 128;\n\
+        Int32 i 32000;\n\
+        Url WOA01 \"http://localhost/junk\";\n\
+    }\n\
+    v {\n\
+        String units \"meter per second\";\n\
+        String long_name \"Vector wind northward component\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+        String DODS_Name \"VWind\", \"VWind\";\n\
+    }\n\
+    lat {\n\
+        String units \"degree North\";\n\
+    }\n\
+    lon {\n\
+        String units \"degree East\";\n\
+    }\n\
+    time {\n\
+        String units \"hours from base_time\";\n\
+    }\n\
+    NC_GLOBAL {\n\
+        String base_time \"88- 10-00:00:00\";\n\
+        String title \" FNOC UV wind components from 1988- 10 to 1988- 13.\";\n\
+    }\n\
+    DODS_EXTRA {\n\
+        String Unlimited_Dimension \"time_a\";\n\
+    }\n\
+}";
+
+string AISMergeTest::fnoc2_merge_ais = "Attributes {\n\
+    u {\n\
+        String units \"meter per second\";\n\
+        String long_name \"UWind\";\n\
+    }\n\
+    v {\n\
+        String units \"meter per second\";\n\
+        String long_name \"VWind\";\n\
+    }\n\
+    lat {\n\
+        String units \"degree North\";\n\
+        String long_name \"Latitude\";\n\
+    }\n\
+    lon {\n\
+        String units \"degree East\";\n\
+        String long_name \"Longitude\";\n\
+    }\n\
+    time {\n\
+    }\n\
+    NC_GLOBAL {\n\
+    }\n\
+    DODS_EXTRA {\n\
+    }\n\
+}";
+
+string AISMergeTest::fnoc3_merge_ais = "Attributes {\n\
+    u {\n\
+        String long_name \"UWind\";\n\
+    }\n\
+    v {\n\
+        String long_name \"VWind\";\n\
+    }\n\
+    lat {\n\
+        String long_name \"Latitude\";\n\
+    }\n\
+    lon {\n\
+        String long_name \"Longitude\";\n\
+    }\n\
+}";
+
+string AISMergeTest::three_fnoc_merge_ais = "Attributes {\n\
+    u {\n\
+        String long_name \"UWind\", \"Vector wind eastward component\";\n\
+        String units \"meter per second\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+    }\n\
+    v {\n\
+        String long_name \"VWind\", \"Vector wind northward component\";\n\
+        String units \"meter per second\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+    }\n\
+    lat {\n\
+        String long_name \"Latitude\";\n\
+        String units \"degree North\";\n\
+    }\n\
+    lon {\n\
+        String long_name \"Longitude\";\n\
+        String units \"degree East\";\n\
+    }\n\
+    time {\n\
+        String units \"hours from base_time\";\n\
+    }\n\
+    NC_GLOBAL {\n\
+        String base_time \"88-245-00:00:00\";\n\
+        String title \" FNOC UV wind components from 1988-245 to 1988-247.\";\n\
+        String AIS_Test_info \"This dataset's name starts with a digit.\";\n\
+    }\n\
+    DODS_EXTRA {\n\
+        String Unlimited_Dimension \"time_a\";\n\
+    }\n\
+}";
+
+CPPUNIT_TEST_SUITE_REGISTRATION(AISMergeTest);
+
+} // 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/chunked-io/test_text_file.txt.chunked b/unit-tests/chunked-io/test_text_file.txt.chunked
new file mode 100644
index 0000000..8807482
Binary files /dev/null and b/unit-tests/chunked-io/test_text_file.txt.chunked differ
diff --git a/unit-tests/chunked-io/test_text_file.txt.plain b/unit-tests/chunked-io/test_text_file.txt.plain
new file mode 100644
index 0000000..9a6ac95
--- /dev/null
+++ b/unit-tests/chunked-io/test_text_file.txt.plain
@@ -0,0 +1,370 @@
+
+// -*- 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.
+
+// Tests for the AISMerge class.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+//#define DODS_DEBUG
+
+#include "Connect.h"
+#include "AISMerge.h"
+#include "debug.h"
+#include <test_config.h>
+
+#include "testFile.h"
+
+using namespace CppUnit;
+
+namespace libdap
+{
+
+class AISMergeTest:public TestFixture {
+  private:
+    AISMerge * ais_merge;
+
+    static string fnoc1, fnoc2, fnoc3, bears, coads, three_fnoc;
+    static string fnoc1_ais, fnoc2_ais, digit_ais, fnoc3_das;
+
+    static string fnoc1_ais_string, bears_1_ais_string, coads_ais_string;
+    static string fnoc1_merge_ais, fnoc2_merge_ais, fnoc3_merge_ais;
+    static string three_fnoc_merge_ais, starts_with_number_ais_string;
+
+    string dump2string(FILE * res) {
+        string stuff = "";
+        char line[256];
+        while (!feof(res) && !ferror(res)
+               && fgets(&line[0], 256, res) != 0)
+             stuff += line;
+
+         return stuff;
+  } public:
+     AISMergeTest() {
+    }
+    ~AISMergeTest() {
+    }
+
+    void setUp() {
+        ais_merge = new AISMerge("ais_testsuite/ais_database.xml");
+    }
+
+    void tearDown() {
+        delete ais_merge;
+        ais_merge = 0;
+    }
+
+    CPPUNIT_TEST_SUITE(AISMergeTest);
+
+    CPPUNIT_TEST(get_ais_resource_test);
+    CPPUNIT_TEST(merge_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void get_ais_resource_test() {
+        try {
+            ResourceVector rv = ais_merge->d_ais_db.get_resource(fnoc1);
+            Response *res = ais_merge->get_ais_resource(rv[0].get_url());
+            string stuff = dump2string(res->get_stream());
+            DBG(cerr << "AIS Resource: " << stuff << endl);
+            CPPUNIT_ASSERT(stuff.find(fnoc1_ais_string)
+                           != string::npos);
+
+            rv = ais_merge->d_ais_db.get_resource(coads);
+            res = ais_merge->get_ais_resource(rv[0].get_url());
+            CPPUNIT_ASSERT(dump2string(res->get_stream()).
+                           find(coads_ais_string)
+                           != string::npos);
+
+            rv = ais_merge->d_ais_db.get_resource(three_fnoc);
+            res = ais_merge->get_ais_resource(rv[0].get_url());
+            CPPUNIT_ASSERT(dump2string(res->get_stream()).
+                           find(starts_with_number_ais_string)
+                           != string::npos);
+        }
+        catch(Error & e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            // If the exception is Not Found then this is not an error; there
+            // are many reasons why the resource might not be found...
+            if (e.get_error_message().find("Not Found:") == string::npos)
+                CPPUNIT_ASSERT(!"Error");
+        }
+    }
+
+    void merge_test() {
+        try {
+            Connect *conn;
+            DAS das;
+            string sof;
+
+            conn = new Connect(fnoc1);  // test overwrite (default)
+            conn->request_das(das);
+            ais_merge->merge(fnoc1, das);
+            FILE2string(sof, of, das.print(of));
+            DBG(cerr << "Merged fnoc1 DAS: " << sof << endl);
+            CPPUNIT_ASSERT(sof.find(fnoc1_merge_ais) != string::npos);
+
+            delete conn;
+            conn = 0;
+            das.erase();
+
+            conn = new Connect(fnoc2);  // test replace
+            conn->request_das(das);
+            ais_merge->merge(fnoc2, das);
+            FILE2string(sof, of, das.print(of));
+            CPPUNIT_ASSERT(sof.find(fnoc2_merge_ais) != string::npos);
+
+            delete conn;
+            conn = 0;
+            das.erase();
+
+            conn = new Connect(fnoc3);  // test fallback
+            conn->request_das(das);     // with a non-empty das, nothing happens
+            ais_merge->merge(fnoc3, das);
+            FILE2string(sof, of, das.print(of));
+            CPPUNIT_ASSERT(sof.find(fnoc3_das) != string::npos);
+
+            das.erase();        // empty das, should add attributes
+            ais_merge->merge(fnoc3, das);
+            FILE2string(sof, of, das.print(of));
+            CPPUNIT_ASSERT(sof.find(fnoc3_merge_ais) != string::npos);
+
+            conn = new Connect(three_fnoc);     // test regexp
+            conn->request_das(das);     // with a non-empty das, nothing happens
+            ais_merge->merge(three_fnoc, das);
+            FILE2string(sof, of, das.print(of));
+            CPPUNIT_ASSERT(sof.find(three_fnoc_merge_ais)
+                           != string::npos);
+        }
+        catch(Error & e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            if (e.get_error_message().find("Not Found:") == string::npos)
+                CPPUNIT_ASSERT(!"Error");
+        }
+    }
+};
+
+string AISMergeTest::fnoc1 =
+    "http://test.opendap.org/opendap/data/nc/fnoc1.nc";
+string AISMergeTest::fnoc2 =
+    "http://test.opendap.org/opendap/data/nc/fnoc2.nc";
+string AISMergeTest::fnoc3 =
+    "http://test.opendap.org/opendap/data/nc/fnoc3.nc";
+string AISMergeTest::bears =
+    "http://test.opendap.org/opendap/data/nc/bears.nc";
+string AISMergeTest::coads =
+    "http://test.opendap.org/opendap/data/nc/coads_climatology.nc";
+string AISMergeTest::three_fnoc =
+    "http://test.opendap.org/opendap/data/nc/3fnoc.nc";
+
+string AISMergeTest::fnoc1_ais =
+    "http://test.opendap.org/ais/fnoc1.nc.das";
+string AISMergeTest::fnoc2_ais =
+    "http://test.opendap.org/ais/fnoc2.nc.das";
+string AISMergeTest::digit_ais = (string)TEST_SRC_DIR + "/ais_testsuite/starts_with_number.das";
+
+string AISMergeTest::fnoc1_ais_string = "Attributes {\n\
+    u {\n\
+	String DODS_Name \"UWind\";\n\
+    }\n\
+    v {\n\
+	String DODS_Name \"VWind\";\n\
+    }\n\
+}";
+
+string AISMergeTest::bears_1_ais_string = "Attributes {\n\
+    bears {\n\
+	String longname \"Test data\";\n\
+    }\n\
+}";
+
+string AISMergeTest::coads_ais_string = "Attributes {\n\
+    COADSX {\n\
+        String long_name \"Longitude\";\n\
+    }\n\
+}";
+
+string AISMergeTest::starts_with_number_ais_string = "Attributes {\n\
+    NC_GLOBAL {\n\
+        String AIS_Test_info \"This dataset's name starts with a digit.\";\n\
+    }\n\
+}";
+
+string AISMergeTest::fnoc3_das = "Attributes {\n\
+    u {\n\
+        String units \"meter per second\";\n\
+        String long_name \"Vector wind eastward component\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+    }\n\
+    v {\n\
+        String units \"meter per second\";\n\
+        String long_name \"Vector wind northward component\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+    }\n\
+    lat {\n\
+        String units \"degree North\";\n\
+    }\n\
+    lon {\n\
+        String units \"degree East\";\n\
+    }\n\
+    time {\n\
+        String units \"hours from base_time\";\n\
+    }\n\
+    NC_GLOBAL {\n\
+        String base_time \"88-245-00:00:00\";\n\
+        String title \" FNOC UV wind components from 1988-245 to 1988-247.\";\n\
+    }\n\
+    DODS_EXTRA {\n\
+        String Unlimited_Dimension \"time_a\";\n\
+    }\n\
+}";
+
+string AISMergeTest::fnoc1_merge_ais = "Attributes {\n\
+    u {\n\
+        String units \"meter per second\";\n\
+        String long_name \"Vector wind eastward component\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+        String DODS_Name \"UWind\", \"UWind\";\n\
+        Byte b 128;\n\
+        Int32 i 32000;\n\
+        Url WOA01 \"http://localhost/junk\";\n\
+    }\n\
+    v {\n\
+        String units \"meter per second\";\n\
+        String long_name \"Vector wind northward component\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+        String DODS_Name \"VWind\", \"VWind\";\n\
+    }\n\
+    lat {\n\
+        String units \"degree North\";\n\
+    }\n\
+    lon {\n\
+        String units \"degree East\";\n\
+    }\n\
+    time {\n\
+        String units \"hours from base_time\";\n\
+    }\n\
+    NC_GLOBAL {\n\
+        String base_time \"88- 10-00:00:00\";\n\
+        String title \" FNOC UV wind components from 1988- 10 to 1988- 13.\";\n\
+    }\n\
+    DODS_EXTRA {\n\
+        String Unlimited_Dimension \"time_a\";\n\
+    }\n\
+}";
+
+string AISMergeTest::fnoc2_merge_ais = "Attributes {\n\
+    u {\n\
+        String units \"meter per second\";\n\
+        String long_name \"UWind\";\n\
+    }\n\
+    v {\n\
+        String units \"meter per second\";\n\
+        String long_name \"VWind\";\n\
+    }\n\
+    lat {\n\
+        String units \"degree North\";\n\
+        String long_name \"Latitude\";\n\
+    }\n\
+    lon {\n\
+        String units \"degree East\";\n\
+        String long_name \"Longitude\";\n\
+    }\n\
+    time {\n\
+    }\n\
+    NC_GLOBAL {\n\
+    }\n\
+    DODS_EXTRA {\n\
+    }\n\
+}";
+
+string AISMergeTest::fnoc3_merge_ais = "Attributes {\n\
+    u {\n\
+        String long_name \"UWind\";\n\
+    }\n\
+    v {\n\
+        String long_name \"VWind\";\n\
+    }\n\
+    lat {\n\
+        String long_name \"Latitude\";\n\
+    }\n\
+    lon {\n\
+        String long_name \"Longitude\";\n\
+    }\n\
+}";
+
+string AISMergeTest::three_fnoc_merge_ais = "Attributes {\n\
+    u {\n\
+        String long_name \"UWind\", \"Vector wind eastward component\";\n\
+        String units \"meter per second\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+    }\n\
+    v {\n\
+        String long_name \"VWind\", \"Vector wind northward component\";\n\
+        String units \"meter per second\";\n\
+        String missing_value \"-32767\";\n\
+        String scale_factor \"0.005\";\n\
+    }\n\
+    lat {\n\
+        String long_name \"Latitude\";\n\
+        String units \"degree North\";\n\
+    }\n\
+    lon {\n\
+        String long_name \"Longitude\";\n\
+        String units \"degree East\";\n\
+    }\n\
+    time {\n\
+        String units \"hours from base_time\";\n\
+    }\n\
+    NC_GLOBAL {\n\
+        String base_time \"88-245-00:00:00\";\n\
+        String title \" FNOC UV wind components from 1988-245 to 1988-247.\";\n\
+        String AIS_Test_info \"This dataset's name starts with a digit.\";\n\
+    }\n\
+    DODS_EXTRA {\n\
+        String Unlimited_Dimension \"time_a\";\n\
+    }\n\
+}";
+
+CPPUNIT_TEST_SUITE_REGISTRATION(AISMergeTest);
+
+} // 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/chunked_iostream_test.cc b/unit-tests/chunked_iostream_test.cc
new file mode 100644
index 0000000..f5ce119
--- /dev/null
+++ b/unit-tests/chunked_iostream_test.cc
@@ -0,0 +1,564 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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 <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "GetOpt.h"
+
+#include "chunked_ostream.h"
+#include "chunked_istream.h"
+
+#include "InternalErr.h"
+#include "test_config.h"
+#include "debug.h"
+
+static bool debug = false;
+
+const string path = (string)TEST_SRC_DIR + "/chunked-io";
+
+#undef DBG
+#define DBG(x) do { if (debug) (x); } while(false);
+
+using namespace std;
+using namespace CppUnit;
+using namespace libdap;
+
+/**
+ * The intent is to test writing to and reading from a chunked iostream,
+ * using various combinations of chunk/buffer sizes and character red/write
+ * sizes. There are three write functions and three read functions and
+ * all combinations are tested.
+ */
+class chunked_iostream_test: public TestFixture {
+private:
+	// This should be big enough to do meaningful timing tests
+	string big_file, big_file_2, big_file_3;
+	// This should be smaller than a single buffer
+	string small_file;
+	// A modest sized text file - makes looking at the results easier
+	string text_file;
+public:
+    chunked_iostream_test()
+    {
+    }
+    ~chunked_iostream_test()
+    {
+    }
+
+    void setUp()
+    {
+    	big_file = path + "/test_big_binary_file.bin";
+    	big_file_2 = path + "/test_big_binary_file_2.bin";
+    	big_file_3 = path + "/test_big_binary_file_3.bin"; // not used yet
+
+    	small_file = path + "/test_small_text_file.txt";
+    	text_file = path + "/test_text_file.txt";
+    }
+
+    void tearDown()
+    {
+    }
+
+    void
+    single_char_write(const string &file, int buf_size)
+    {
+    	fstream infile(file.c_str(), ios::in|ios::binary);
+    	DBG(cerr << "infile: " << file << endl);
+    	if (!infile.good())
+    		CPPUNIT_FAIL("File not open or eof");
+
+    	string out = file + ".chunked";
+    	fstream outfile(out.c_str(), ios::out|ios::binary);
+
+    	chunked_ostream chunked_outfile(outfile, buf_size);
+
+    	char c;
+    	infile.read(&c, 1);
+    	int num = infile.gcount();
+    	while (num > 0 && !infile.eof()) {
+    		chunked_outfile.write(&c, num);
+    		infile.read(&c, 1);
+    		num = infile.gcount();
+    	}
+
+    	if (num > 0 && !infile.bad()) {
+    		chunked_outfile.write(&c, num);
+    	}
+
+    	chunked_outfile.flush();
+    }
+
+    void
+    write_128char_data(const string &file, int buf_size)
+    {
+    	fstream infile(file.c_str(), ios::in|ios::binary);
+    	if (!infile.good())
+    		CPPUNIT_FAIL("File not open or eof");
+
+    	string out = file + ".chunked";
+    	fstream outfile(out.c_str(), ios::out|ios::binary);
+
+    	chunked_ostream chunked_outfile(outfile, buf_size);
+
+    	char str[128];
+    	infile.read(str, 128);
+    	int num = infile.gcount();
+    	while (num > 0 && !infile.eof()) {
+    		chunked_outfile.write(str, num);
+    		infile.read(str, 128);
+    		num = infile.gcount();
+    	}
+
+    	if (num > 0 && !infile.bad()) {
+    		chunked_outfile.write(str, num);
+    	}
+
+        chunked_outfile.flush();
+    }
+
+    // This will not work with the small text file. This code assume that
+    // the file to be written has at least 24 bytes for the first chunk,
+    // which is deliberately sent using flush before the buffer is full and
+    // then has at least 48 more bytes (but ideally 49, because this code
+    // tries to send an End chunk with one or more bytes as opposed to
+    // sending the last data chunk with fewer than buf_size and then sending a
+    // zero length END chunk).
+    void
+    write_24char_data_with_error_option(const string &file, int buf_size, bool error = false)
+    {
+    	fstream infile(file.c_str(), ios::in|ios::binary);
+    	if (!infile.good())
+    		CPPUNIT_FAIL("File not open or eof");
+
+    	string out = file + ".chunked";
+    	fstream outfile(out.c_str(), ios::out|ios::binary);
+
+    	chunked_ostream chunked_outfile(outfile, buf_size);
+
+    	try {
+    		char str[24];
+    		infile.read(str, 24);
+    		int num = infile.gcount();
+    		if (num > 0 && !infile.eof()) {
+    			chunked_outfile.write(str, num);
+    			chunked_outfile.flush();
+    		}
+
+    		infile.read(str, 24);
+    		num = infile.gcount();
+    		if (num > 0 && !infile.eof()) chunked_outfile.write(str, num);
+
+    		// Send an error chunk; the 24 bytes read here are lost...
+    		if (error)
+    			throw Error("Testing error transmission");
+
+    		infile.read(str, 24);
+    		num = infile.gcount();
+    		while (num == 24 && !infile.eof()) {
+    			chunked_outfile.write(str, num);
+    			infile.read(str, 24);
+    			num = infile.gcount();
+    		}
+
+    		if (num > 0 && !infile.bad()) {
+    			chunked_outfile.write(str, num);
+    		}
+
+    		// flush() calls sync() which forces a DATA chunk to be sent, regardless of
+    		// the amount of data in the buffer. When the stream is destroyed, end_chunk()
+    		// is sent with the remain chars, so removing flush() here ensures that we test
+    		// a non-empty END chunk.
+            // chunked_outfile.flush();
+    	}
+    	catch (Error &e) {
+    		chunked_outfile.write_err_chunk(e.get_error_message());
+    	}
+    }
+
+    void
+    single_char_read(const string &file, int buf_size)
+    {
+    	string in = file + ".chunked";
+    	fstream infile(in.c_str(), ios::in|ios::binary);
+    	if (!infile.good())
+    		CPPUNIT_FAIL("File not open or eof");
+#if BYTE_ORDER_PREFIX
+    	chunked_istream chunked_infile(infile, buf_size, 0x00);
+#else
+    	chunked_istream chunked_infile(infile, buf_size);
+#endif
+    	string out = file + ".plain";
+    	fstream outfile(out.c_str(), ios::out|ios::binary);
+
+    	char c;
+    	int count = 1;
+    	chunked_infile.read(&c, 1);
+    	int num = chunked_infile.gcount();
+    	DBG(cerr << "num: " << num << ", " << count++ << endl);
+    	while (num > 0 && !chunked_infile.eof()) {
+    		outfile.write(&c, num);
+    		chunked_infile.read(&c, 1);
+    		num = chunked_infile.gcount();
+    		DBG(cerr << "num: " << num << ", " <<  count++ << ", eof: " << chunked_infile.eof() << endl);
+    	}
+
+    	DBG(cerr << "eof is :" << chunked_infile.eof() << ", num: " << num << endl);
+
+    	if (num > 0 && !chunked_infile.bad())
+    	    outfile.write(&c, num);
+
+    	outfile.flush();
+    }
+
+    void
+    read_128char_data(const string &file, int buf_size)
+    {
+    	string in = file + ".chunked";
+    	fstream infile(in.c_str(), ios::in|ios::binary);
+    	if (!infile.good())
+    		cerr << "File not open or eof" << endl;
+    	chunked_istream chunked_infile(infile, buf_size);
+
+    	string out = file + ".plain";
+    	fstream outfile(out.c_str(), ios::out|ios::binary);
+
+    	char str[128];
+    	int count = 1;
+    	chunked_infile.read(str, 128);
+    	int num = chunked_infile.gcount();
+    	DBG(cerr << "num: " << num << ", " << count++ << endl);
+    	while (num > 0 && !chunked_infile.eof()) {
+    		outfile.write(str, num);
+    		chunked_infile.read(str, 128);
+    		num = chunked_infile.gcount();
+    		DBG(cerr << "num: " << num << ", " <<  count++ << ", eof: " << chunked_infile.eof() << endl);
+    	}
+
+    	if (num > 0 && !chunked_infile.bad()) {
+    		outfile.write(str, num);
+    	}
+
+    	outfile.flush();
+    }
+
+    void
+    read_24char_data_with_error_option(const string &file, int buf_size)
+    {
+    	string in = file + ".chunked";
+    	fstream infile(in.c_str(), ios::in|ios::binary);
+    	if (!infile.good())
+    		cerr << "File not open or eof" << endl;
+    	chunked_istream chunked_infile(infile, buf_size);
+
+    	string out = file + ".plain";
+    	fstream outfile(out.c_str(), ios::out|ios::binary);
+
+    	try {
+#if 0
+    		chunked_infile.read(str, 24);
+    		int num = chunked_infile.gcount();
+    		if (num > 0 && !chunked_infile.eof()) {
+    			outfile.write(str, num);
+    			outfile.flush();
+    		}
+#endif
+    		char str[24];
+    		chunked_infile.read(str, 24);
+    		int num = chunked_infile.gcount();
+    		while (num > 0 && !chunked_infile.eof()) {
+    			outfile.write(str, num);
+    			chunked_infile.read(str, 24);
+    			num = chunked_infile.gcount();
+    		}
+
+    		// The chunked_istream uses a chunked_inbuf and that signals error
+    		// using EOF. The error message is stored in the buffer and can be
+    		// detected and accessed using the error() error_message() methods
+    		// that both the buffer and istream classes have.
+    		if (chunked_infile.error())
+    			throw Error("Found an error in the stream");
+
+    		if (num > 0 && !chunked_infile.bad()) {
+    			outfile.write(str, num);
+    		}
+
+    		outfile.flush();
+    	}
+    	catch (Error &e) {
+    		DBG(cerr << "Error chunk found: " << e.get_error_message() << endl);
+    		throw;
+    	}
+    }
+
+    // these are the tests
+    void test_write_1_read_1_small_file() {
+    	single_char_write(small_file, 32);
+    	single_char_read(small_file, 32);
+    	string cmp = "cmp " + small_file + " " + small_file + ".plain";
+    	CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_1_read_1_text_file() {
+    	single_char_write(text_file, 32);
+    	single_char_read(text_file, 32);
+    	string cmp = "cmp " + text_file + " " + text_file + ".plain";
+    	CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_1_read_1_big_file() {
+        single_char_write(big_file, 28);
+        single_char_read(big_file, 28);
+        string cmp = "cmp " + big_file + " " + big_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+    void test_write_1_read_1_big_file_2() {
+        single_char_write(big_file_2, 28);
+        single_char_read(big_file_2, 28);
+        string cmp = "cmp " + big_file_2 + " " + big_file_2 + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    // these are the tests
+    void test_write_1_read_128_small_file() {
+        single_char_write(small_file, 32);
+        read_128char_data(small_file, 32);
+        string cmp = "cmp " + small_file + " " + small_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_1_read_128_text_file() {
+        single_char_write(text_file, 32);
+        read_128char_data(text_file, 32);
+        string cmp = "cmp " + text_file + " " + text_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_1_read_128_big_file() {
+        single_char_write(big_file, 28);
+        read_128char_data(big_file, 28);
+        string cmp = "cmp " + big_file + " " + big_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_1_read_128_big_file_2() {
+        single_char_write(big_file_2, 28);
+        read_128char_data(big_file_2, 28);
+        string cmp = "cmp " + big_file_2 + " " + big_file_2 + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    // 24 char write units
+
+    void test_write_24_read_1_text_file() {
+    	write_24char_data_with_error_option(text_file, 32);
+    	single_char_read(text_file, 32);
+        string cmp = "cmp " + text_file + " " + text_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_24_read_1_big_file() {
+    	write_24char_data_with_error_option(big_file, 1024);
+    	DBG(cerr << "Wrote the file" << endl);
+
+    	single_char_read(big_file, 1024);
+        string cmp = "cmp " + big_file + " " + big_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_24_read_1_big_file_2() {
+    	write_24char_data_with_error_option(big_file_2, 1024);
+    	DBG(cerr << "Wrote the file" << endl);
+
+    	single_char_read(big_file_2, 1024);
+        string cmp = "cmp " + big_file_2 + " " + big_file_2 + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_24_read_128_text_file() {
+    	write_24char_data_with_error_option(text_file, 32);
+        read_128char_data(text_file, 32);
+        string cmp = "cmp " + text_file + " " + text_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_24_read_128_big_file() {
+    	write_24char_data_with_error_option(big_file, 28);
+    	DBG(cerr << "Wrote the file" << endl);
+
+        read_128char_data(big_file, 28);
+        string cmp = "cmp " + big_file + " " + big_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_24_read_128_big_file_2() {
+    	write_24char_data_with_error_option(big_file_2, 28);
+        read_128char_data(big_file_2, 28);
+        string cmp = "cmp " + big_file_2 + " " + big_file_2 + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    // 128 char writes
+    void test_write_128_read_1_text_file() {
+    	write_128char_data(text_file, 32);
+    	single_char_read(text_file, 32);
+        string cmp = "cmp " + text_file + " " + text_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_128_read_1_big_file() {
+    	write_128char_data(big_file, 32);
+    	DBG(cerr << "Wrote the file" << endl);
+
+    	single_char_read(big_file, 32);
+        string cmp = "cmp " + big_file + " " + big_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_128_read_1_big_file_2() {
+    	write_128char_data(big_file_2, 32);
+    	DBG(cerr << "Wrote the file" << endl);
+
+    	single_char_read(big_file_2, 1024);
+        string cmp = "cmp " + big_file_2 + " " + big_file_2 + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_128_read_128_text_file() {
+    	write_128char_data(text_file, 32);
+        read_128char_data(text_file, 32);
+        string cmp = "cmp " + text_file + " " + text_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_128_read_128_big_file() {
+    	write_128char_data(big_file, 28);
+    	DBG(cerr << "Wrote the file" << endl);
+
+        read_128char_data(big_file, 28);
+        string cmp = "cmp " + big_file + " " + big_file + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    void test_write_128_read_128_big_file_2() {
+    	write_128char_data(big_file_2, 28);
+        read_128char_data(big_file_2, 28);
+        string cmp = "cmp " + big_file_2 + " " + big_file_2 + ".plain";
+        CPPUNIT_ASSERT(system(cmp.c_str()) == 0);
+    }
+
+    // Send an error
+
+    void test_write_24_read_24_big_file_2_error() {
+		write_24char_data_with_error_option(big_file_2, 2048, true /*error*/);
+		try {
+			read_24char_data_with_error_option(big_file_2, 2048);
+			CPPUNIT_FAIL("Should have caught an error message");
+		}
+		catch (Error &e) {
+			CPPUNIT_ASSERT(!e.get_error_message().empty());
+		}
+	}
+
+    CPPUNIT_TEST_SUITE(chunked_iostream_test);
+
+    CPPUNIT_TEST(test_write_1_read_1_small_file);
+    CPPUNIT_TEST(test_write_1_read_1_text_file);
+    CPPUNIT_TEST(test_write_1_read_1_big_file);
+    CPPUNIT_TEST(test_write_1_read_1_big_file_2);
+
+    CPPUNIT_TEST(test_write_1_read_128_small_file);
+    CPPUNIT_TEST(test_write_1_read_128_text_file);
+    CPPUNIT_TEST(test_write_1_read_128_big_file);
+    CPPUNIT_TEST(test_write_1_read_128_big_file_2);
+
+    CPPUNIT_TEST(test_write_24_read_1_text_file);
+    CPPUNIT_TEST(test_write_24_read_1_big_file);
+    CPPUNIT_TEST(test_write_24_read_1_big_file_2);
+
+    CPPUNIT_TEST(test_write_24_read_128_text_file);
+    CPPUNIT_TEST(test_write_24_read_128_big_file);
+    CPPUNIT_TEST(test_write_24_read_128_big_file_2);
+
+    CPPUNIT_TEST(test_write_128_read_1_text_file);
+    CPPUNIT_TEST(test_write_128_read_1_big_file);
+    CPPUNIT_TEST(test_write_128_read_1_big_file_2);
+
+    CPPUNIT_TEST(test_write_128_read_128_text_file);
+    CPPUNIT_TEST(test_write_128_read_128_big_file);
+    CPPUNIT_TEST(test_write_128_read_128_big_file_2);
+
+    CPPUNIT_TEST(test_write_24_read_24_big_file_2_error);
+
+    CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(chunked_iostream_test);
+
+int
+main(int argc, char *argv[])
+{
+    GetOpt getopt(argc, argv, "d");
+    char option_char;
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+            case 'd':
+                debug = 1;  // debug is a static global
+                break;
+            default:
+                break;
+        }
+
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    bool wasSuccessful = true;
+    string test = "";
+    int i = getopt.optind;
+    if (i == argc) {
+        // run them all
+        wasSuccessful = runner.run("");
+    }
+    else {
+        while (i < argc) {
+            test = string("chunked_iostream_test::") + argv[i++];
+            if (debug)
+                cerr << "Running " << test << endl;
+            wasSuccessful = wasSuccessful && runner.run(test);
+        }
+    }
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/dds-testsuite/3B42.980909.5.HDF.dmr b/unit-tests/dds-testsuite/3B42.980909.5.HDF.dmr
new file mode 100644
index 0000000..33074a2
--- /dev/null
+++ b/unit-tests/dds-testsuite/3B42.980909.5.HDF.dmr
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="3B42.980909.5.HDF">
+    <Dimension name="scan" size="1"/>
+    <Dimension name="longitude" size="360"/>
+    <Dimension name="latitude" size="80"/>
+    <Structure name="DATA_GRANULE">
+        <Structure name="PlanetaryGrid">
+            <Float32 name="percipitate">
+                <Dim name="/scan"/>
+                <Dim name="/longitude"/>
+                <Dim name="/latitude"/>
+            </Float32>
+            <Float32 name="relError">
+                <Dim name="/scan"/>
+                <Dim name="/longitude"/>
+                <Dim name="/latitude"/>
+            </Float32>
+        </Structure>
+    </Structure>
+</Dataset>
diff --git a/unit-tests/dds-testsuite/3B42.980909.5.hacked.2.HDF.attr.dmr b/unit-tests/dds-testsuite/3B42.980909.5.hacked.2.HDF.attr.dmr
new file mode 100644
index 0000000..405355d
--- /dev/null
+++ b/unit-tests/dds-testsuite/3B42.980909.5.hacked.2.HDF.attr.dmr
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="3B42.980909.5.HDF">
+    <Dimension name="scan" size="1"/>
+    <Dimension name="longitude" size="360"/>
+    <Dimension name="latitude" size="80"/>
+    <Structure name="DATA_GRANULE">
+        <Structure name="PlanetaryGrid">
+            <Float32 name="percipitate">
+                <Dim name="/scan"/>
+                <Dim name="/longitude"/>
+                <Dim name="/latitude"/>
+            </Float32>
+            <Float32 name="relError">
+                <Dim name="/scan"/>
+                <Dim name="/longitude"/>
+                <Dim name="/latitude"/>
+            </Float32>
+        </Structure>
+    </Structure>
+    <Attribute name="HDF_GLOBAL" type="Container"/>
+    <Attribute name="CoreMetadata" type="Container">
+        <Attribute name="OrbitNumber" type="Container">
+            <Attribute name="Value" type="Int32">
+                <Value>-9999</Value>
+            </Attribute>
+            <Attribute name="Data_Location" type="String">
+                <Value>PGE</Value>
+            </Attribute>
+            <Attribute name="Mandatory" type="String">
+                <Value>FALSE</Value>
+            </Attribute>
+        </Attribute>
+        <Attribute name="RangeBeginningDate" type="Container">
+            <Attribute name="Value" type="String">
+                <Value>1998/09/09</Value>
+            </Attribute>
+            <Attribute name="Data_Location" type="String">
+                <Value>PGE</Value>
+            </Attribute>
+            <Attribute name="Mandatory" type="String">
+                <Value>FALSE</Value>
+            </Attribute>
+        </Attribute>
+    </Attribute>
+    <Attribute name="percipitate" type="Container">
+        <Attribute name="name" type="String">
+            <Value>dim_0_scan</Value>
+            <Value>dim_1_longitude</Value>
+            <Value>dim_2_latitude</Value>
+        </Attribute>
+    </Attribute>
+    <Attribute name="relError" type="Container">
+        <Attribute name="name" type="String">
+            <Value>dim_0_scan</Value>
+            <Value>dim_1_longitude</Value>
+            <Value>dim_2_latitude</Value>
+        </Attribute>
+    </Attribute>
+</Dataset>
diff --git a/unit-tests/dds-testsuite/3B42.980909.5.hacked.2.HDF.das b/unit-tests/dds-testsuite/3B42.980909.5.hacked.2.HDF.das
new file mode 100644
index 0000000..8afd5dc
--- /dev/null
+++ b/unit-tests/dds-testsuite/3B42.980909.5.hacked.2.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 {
+        String name "dim_0_scan";
+    }
+    percipitate {
+        String name "dim_1_longitude";
+    }
+    percipitate {
+        String name "dim_2_latitude";
+    }
+    relError {
+        String name "dim_0_scan";
+    }
+    relError {
+        String name "dim_1_longitude";
+    }
+    relError {
+        String name "dim_2_latitude";
+    }
+}
diff --git a/unit-tests/dds-testsuite/S2000415.HDF.dmr b/unit-tests/dds-testsuite/S2000415.HDF.dmr
new file mode 100644
index 0000000..5a76c4b
--- /dev/null
+++ b/unit-tests/dds-testsuite/S2000415.HDF.dmr
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="S2000415.HDF">
+    <Dimension name="row" size="458"/>
+    <Dimension name="WVC" size="24"/>
+    <Dimension name="position" size="4"/>
+    <Structure name="NSCAT Rev 20">
+        <Int16 name="WVC_Lat">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </Int16>
+        <UInt16 name="WVC_Lon">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </UInt16>
+        <Byte name="Num_Sigma0">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </Byte>
+        <Byte name="Num_Beam_12">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </Byte>
+        <Byte name="Num_Beam_34">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </Byte>
+        <Byte name="Num_Beam_56">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </Byte>
+        <Byte name="Num_Beam_78">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </Byte>
+        <Byte name="WVC_Quality_Flag">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </Byte>
+        <UInt16 name="Mean_Wind">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </UInt16>
+        <UInt16 name="Wind_Speed">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+            <Dim name="/position"/>
+        </UInt16>
+        <UInt16 name="Wind_Dir">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+            <Dim name="/position"/>
+        </UInt16>
+        <UInt16 name="Error_Speed">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+            <Dim name="/position"/>
+        </UInt16>
+        <UInt16 name="Error_Dir">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+            <Dim name="/position"/>
+        </UInt16>
+        <Int16 name="MLE_Likelihood">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+            <Dim name="/position"/>
+        </Int16>
+        <Byte name="Num_Ambigs">
+            <Dim name="/row"/>
+            <Dim name="/WVC"/>
+        </Byte>
+        <Sequence name="SwathIndex">
+            <Structure name="begin">
+                <Int16 name="begin__0"/>
+            </Structure>
+        </Sequence>
+        <Sequence name="NSCAT L2">
+            <Structure name="Mean_Time">
+                <String name="Mean_Time__0"/>
+            </Structure>
+            <Structure name="Low_Wind_Speed_Flag">
+                <UInt32 name="Low_Wind_Speed_Flag__0"/>
+            </Structure>
+            <Structure name="High_Wind_Speed_Flag">
+                <UInt32 name="High_Wind_Speed_Flag__0"/>
+            </Structure>
+        </Sequence>
+    </Structure>
+</Dataset>
diff --git a/unit-tests/dds-testsuite/coads_climatology.nc.dmr b/unit-tests/dds-testsuite/coads_climatology.nc.dmr
new file mode 100644
index 0000000..6a9ba3b
--- /dev/null
+++ b/unit-tests/dds-testsuite/coads_climatology.nc.dmr
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="coads_climatology.nc">
+    <Dimension name="TIME" size="12"/>
+    <Dimension name="COADSY" size="90"/>
+    <Dimension name="COADSX" size="180"/>
+    <Float64 name="TIME">
+        <Dim name="/TIME"/>
+    </Float64>
+    <Float64 name="COADSY">
+        <Dim name="/COADSY"/>
+    </Float64>
+    <Float64 name="COADSX">
+        <Dim name="/COADSX"/>
+    </Float64>
+    <Float32 name="SST">
+        <Dim name="/TIME"/>
+        <Dim name="/COADSY"/>
+        <Dim name="/COADSX"/>
+        <Map name="TIME"/>
+        <Map name="COADSY"/>
+        <Map name="COADSX"/>
+    </Float32>
+    <Float32 name="AIRT">
+        <Dim name="/TIME"/>
+        <Dim name="/COADSY"/>
+        <Dim name="/COADSX"/>
+        <Map name="TIME"/>
+        <Map name="COADSY"/>
+        <Map name="COADSX"/>
+    </Float32>
+    <Float32 name="UWND">
+        <Dim name="/TIME"/>
+        <Dim name="/COADSY"/>
+        <Dim name="/COADSX"/>
+        <Map name="TIME"/>
+        <Map name="COADSY"/>
+        <Map name="COADSX"/>
+    </Float32>
+    <Float32 name="VWND">
+        <Dim name="/TIME"/>
+        <Dim name="/COADSY"/>
+        <Dim name="/COADSX"/>
+        <Map name="TIME"/>
+        <Map name="COADSY"/>
+        <Map name="COADSX"/>
+    </Float32>
+</Dataset>
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.16.exp b/unit-tests/dds-testsuite/dds-test.0/test.16.exp
index 8080cf7..8d0c71b 100644
--- a/unit-tests/dds-testsuite/dds-test.0/test.16.exp
+++ b/unit-tests/dds-testsuite/dds-test.0/test.16.exp
@@ -2,7 +2,7 @@
 # expect/tcl code to test the dds parser and scanner
 # jhrg
 #
-# $Id: test.16.exp 11906 2005-08-08 19:51:43Z root $
+# $Id$
 
 global comp_output		# contains output from dds-test_start
 global verbose			# this and srcdir are set by runtest.exp
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.17.exp b/unit-tests/dds-testsuite/dds-test.0/test.17.exp
index 77c8d49..b36354a 100644
--- a/unit-tests/dds-testsuite/dds-test.0/test.17.exp
+++ b/unit-tests/dds-testsuite/dds-test.0/test.17.exp
@@ -2,7 +2,7 @@
 # expect/tcl code to test the dds parser and scanner
 # jhrg
 #
-# $Id: test.17.exp 11906 2005-08-08 19:51:43Z root $
+# $Id$
 
 global comp_output		# contains output from dds-test_start
 global verbose			# this and srcdir are set by runtest.exp
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.18.exp b/unit-tests/dds-testsuite/dds-test.0/test.18.exp
index d17b710..4e74c07 100644
--- a/unit-tests/dds-testsuite/dds-test.0/test.18.exp
+++ b/unit-tests/dds-testsuite/dds-test.0/test.18.exp
@@ -2,7 +2,7 @@
 # expect/tcl code to test the dds parser and scanner
 # jhrg
 #
-# $Id: test.18.exp 11906 2005-08-08 19:51:43Z root $
+# $Id$
 
 global comp_output		# contains output from dds-test_start
 global verbose			# this and srcdir are set by runtest.exp
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.19.exp b/unit-tests/dds-testsuite/dds-test.0/test.19.exp
index 0d7117b..87ac9f7 100644
--- a/unit-tests/dds-testsuite/dds-test.0/test.19.exp
+++ b/unit-tests/dds-testsuite/dds-test.0/test.19.exp
@@ -2,7 +2,7 @@
 # expect/tcl code to test the dds parser and scanner
 # jhrg
 #
-# $Id: test.19.exp 11906 2005-08-08 19:51:43Z root $
+# $Id$
 
 global comp_output		# contains output from dds-test_start
 global verbose			# this and srcdir are set by runtest.exp
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.20.exp b/unit-tests/dds-testsuite/dds-test.0/test.20.exp
index 27186e5..9aca215 100644
--- a/unit-tests/dds-testsuite/dds-test.0/test.20.exp
+++ b/unit-tests/dds-testsuite/dds-test.0/test.20.exp
@@ -2,7 +2,7 @@
 # expect/tcl code to test the dds parser and scanner
 # jhrg
 #
-# $Id: test.20.exp 11906 2005-08-08 19:51:43Z root $
+# $Id$
 
 global comp_output		# contains output from dds-test_start
 global verbose			# this and srcdir are set by runtest.exp
diff --git a/unit-tests/dds-testsuite/fnoc1.nc.dmr b/unit-tests/dds-testsuite/fnoc1.nc.dmr
new file mode 100644
index 0000000..ba7a9b5
--- /dev/null
+++ b/unit-tests/dds-testsuite/fnoc1.nc.dmr
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="fnoc1.nc">
+    <Dimension name="time_a" size="16"/>
+    <Dimension name="lat" size="17"/>
+    <Dimension name="lon" size="21"/>
+    <Dimension name="time" size="16"/>
+    <Int16 name="u">
+        <Dim name="/time_a"/>
+        <Dim name="/lat"/>
+        <Dim name="/lon"/>
+    </Int16>
+    <Int16 name="v">
+        <Dim name="/time_a"/>
+        <Dim name="/lat"/>
+        <Dim name="/lon"/>
+    </Int16>
+    <Float32 name="lat">
+        <Dim name="/lat"/>
+    </Float32>
+    <Float32 name="lon">
+        <Dim name="/lon"/>
+    </Float32>
+    <Float32 name="time">
+        <Dim name="/time"/>
+    </Float32>
+</Dataset>
diff --git a/unit-tests/dds-testsuite/test.1.attr.dmr b/unit-tests/dds-testsuite/test.1.attr.dmr
new file mode 100644
index 0000000..d0dc48e
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.1.attr.dmr
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="data1">
+    <Byte name="b">
+        <Attribute name="long_name" type="String">
+            <Value>byte_b</Value>
+        </Attribute>
+    </Byte>
+    <Int32 name="i">
+        <Attribute name="long_name" type="String">
+            <Value>int32_i</Value>
+        </Attribute>
+        <Attribute name="scale_factor" type="Byte">
+            <Value>1.2</Value>
+        </Attribute>
+        <Attribute name="coefs" type="Int32">
+            <Value>2</Value>
+            <Value>3</Value>
+            <Value>4</Value>
+        </Attribute>
+    </Int32>
+    <Int32 name="j"/>
+</Dataset>
diff --git a/unit-tests/dds-testsuite/test.1.das b/unit-tests/dds-testsuite/test.1.das
new file mode 100644
index 0000000..d170451
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.1.das
@@ -0,0 +1,11 @@
+Attributes {
+    b {
+        String long_name "byte_b";
+    }
+    i {
+	String long_name "int32_i";
+  	Float32 scale_factor 1.2;
+	int32 coefs 2, 3, 4;
+    }
+}
+
diff --git a/unit-tests/dds-testsuite/test.1.dmr b/unit-tests/dds-testsuite/test.1.dmr
new file mode 100644
index 0000000..dab4ae2
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.1.dmr
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Dataset xmlns="http://xml.opendap.org/ns/DAP/4.0#" dapVersion="4.0" dmrVersion="1.0" name="data1">
+    <Byte name="b"/>
+    <Int32 name="i"/>
+    <Int32 name="j"/>
+</Dataset>
diff --git a/unit-tests/ddsT.cc b/unit-tests/ddsT.cc
index 78d764c..e4bdb27 100644
--- a/unit-tests/ddsT.cc
+++ b/unit-tests/ddsT.cc
@@ -159,7 +159,9 @@ public:
 	    bt = factory->NewStr( "var6" ) ;
 	    dds.add_var( bt ) ;
 	    delete bt ;
-	    bt = factory->NewArray( "var7", factory->NewInt16( "" ) ) ;
+	    BaseType *tbt = factory->NewInt16( "" ) ;
+	    bt = factory->NewArray( "var7", tbt ) ;
+	    delete tbt; tbt = 0;
 	    dds.add_var( bt ) ;
 	    delete bt ;
 	    bt = factory->NewStructure( "var8" ) ;
@@ -172,6 +174,7 @@ public:
 	    s->add_var( bts1 ) ;
 	    delete bts1 ; bts1 = 0 ;
 	    dds.add_var( bt ) ;
+	    delete bt; bt = 0;
 	}
 	catch( InternalErr &e )
 	{
@@ -451,7 +454,9 @@ public:
 	    bt = factory->NewStr( "c1var2" ) ;
 	    dds.add_var( bt ) ;
 	    delete bt ;
-	    bt = factory->NewArray( "c1var3", factory->NewInt16( "" ) ) ;
+	    BaseType *tbt = factory->NewInt16( "" );
+	    bt = factory->NewArray( "c1var3", tbt ) ;
+	    delete tbt; tbt = 0;
 	    dds.add_var( bt ) ;
 	    delete bt ;
 	}
diff --git a/unit-tests/ddx-testsuite/dataddx_without_top_headers.dap b/unit-tests/ddx-testsuite/dataddx_without_top_headers.dap
index 60301bb..5d3d618 100644
Binary files a/unit-tests/ddx-testsuite/dataddx_without_top_headers.dap and b/unit-tests/ddx-testsuite/dataddx_without_top_headers.dap differ
diff --git a/unit-tests/generalUtilTest.cc b/unit-tests/generalUtilTest.cc
index dd98684..256136c 100644
--- a/unit-tests/generalUtilTest.cc
+++ b/unit-tests/generalUtilTest.cc
@@ -1,4 +1,3 @@
-
 // -*- mode: c++; c-basic-offset:4 -*-
 
 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
@@ -45,20 +44,26 @@ using std::string;
 using namespace CppUnit;
 using namespace libdap;
 
-class generalUtilTest : public TestFixture {
+class generalUtilTest: public TestFixture {
 private:
 
 public:
-    generalUtilTest() {}
-    ~generalUtilTest() {}
+    generalUtilTest()
+    {
+    }
+    ~generalUtilTest()
+    {
+    }
 
-    void setUp() {
+    void setUp()
+    {
     }
 
-    void tearDown() {
+    void tearDown()
+    {
     }
 
-    CPPUNIT_TEST_SUITE(generalUtilTest);
+CPPUNIT_TEST_SUITE(generalUtilTest);
 
     CPPUNIT_TEST(octal_to_hex_test);
     CPPUNIT_TEST(prune_spaces_test);
@@ -78,26 +83,31 @@ public:
     CPPUNIT_TEST(glob_test_2);
     CPPUNIT_TEST(glob_test_3);
 
-    CPPUNIT_TEST_SUITE_END();
+    CPPUNIT_TEST_SUITE_END()
+    ;
 
     // Tests for methods
-    void glob_test_1() {
+    void glob_test_1()
+    {
         string t = "This is a test";
         int status = glob("This is a test", t.c_str());
         CPPUNIT_ASSERT(status == 0);
     }
-    void glob_test_2() {
+    void glob_test_2()
+    {
         string t = "This is a test";
         int status = glob("This * test", t.c_str());
         CPPUNIT_ASSERT(status == 0);
     }
-    void glob_test_3() {
+    void glob_test_3()
+    {
         string t = "This is a test";
         int status = glob("* is * test", t.c_str());
         CPPUNIT_ASSERT(status == 0);
     }
 
-    void octal_to_hex_test() {
+    void octal_to_hex_test()
+    {
         string hex;
         hex = octal_to_hex("000");
         CPPUNIT_ASSERT(hex == "00");
@@ -109,248 +119,261 @@ public:
         CPPUNIT_ASSERT(hex == "3f");
     }
 
-    void prune_spaces_test() {
-	string test_server = "http://test.opendap.org";
-	CPPUNIT_ASSERT(prune_spaces(test_server) == test_server);
+    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_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 = "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 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);
+        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 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 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 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 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");
-	//cerr << "www2id(\"OPF_MaxSpectralPixelsMissing%d4\"): " << www2id("OPF_MaxSpectralPixelsMissing%d4") << endl;
-	//CPPUNIT_ASSERT(www2id("OPF_MaxSpectralPixelsMissing%d4") == "OPF_MaxSpectralPixelsMissing?");
+    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");
+        //cerr << "www2id(\"OPF_MaxSpectralPixelsMissing%d4\"): " << www2id("OPF_MaxSpectralPixelsMissing%d4") << endl;
+        //CPPUNIT_ASSERT(www2id("OPF_MaxSpectralPixelsMissing%d4") == "OPF_MaxSpectralPixelsMissing?");
     }
 
     // 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)));
+    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);
-	}
+        if (*s->begin() == '\"' && *(s->end() - 1) == '\"') {
+            s->erase(s->begin());
+            s->erase(s->end() - 1);
+        }
 
-	return s;
+        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 ce_string_parse_test()
+    {
+        string *str = new string("testing");
+        string *str1 = new string("testing");
+        string *result = store_str(str->c_str());
+        CPPUNIT_ASSERT(*result == *str1);
+        delete result;
+        *str = "\"testing\"";
+        *str1 = "testing";
+        result = store_str(str->c_str());
+        CPPUNIT_ASSERT(*result == *str1);
+        delete result;
+        *str = "\"test%20ing\"";
+        *str1 = "test ing";
+        result = store_str(str->c_str());
+        CPPUNIT_ASSERT(*result == *str1);
+        delete result;
+        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 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");
+    void unescattr_test()
+    {
+        CPPUNIT_ASSERT(unescattr("attr") == "attr");
 
-	DBG(cerr << "XXX" << unescattr("\\\"attr") << "XXX" << endl);
-	CPPUNIT_ASSERT(unescattr("\\\"attr") == "\"attr");
+        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("\\\"attr") << "XXX" << endl);
+        CPPUNIT_ASSERT(unescattr("\\\"attr") == "\"attr");
 
-	DBG(cerr << "XXX" << unescattr("\\\\200\\\\177A") << "XXX" << endl);
-	CPPUNIT_ASSERT(unescattr("\\\\200\\\\177A") == string(A_200_177));
+        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\\\\177AZ$&") << "XXX" << endl);
 
-	DBG(cerr << "XXX" << unescattr("\\\\200") << "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);
+    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;
+        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;
+        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);
+        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 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\"");
+    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** )
+int main(int, char**)
 {
     CppUnit::TextTestRunner runner;
-    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
 
-    bool wasSuccessful = runner.run( "", false ) ;
+    bool wasSuccessful = runner.run("", false);
 
     return wasSuccessful ? 0 : 1;
 }
 
-
diff --git a/unit-tests/structT.cc b/unit-tests/structT.cc
index 3b8e1a5..e742919 100644
--- a/unit-tests/structT.cc
+++ b/unit-tests/structT.cc
@@ -71,6 +71,7 @@ public:
 		delete bt;
 		bt = 0;
 
+		// TODO Check Does this leak the Int16
 		Array *abt = factory->NewArray("name_array", factory->NewInt16("array_int"));
 		abt->append_dim(4, "dim1");
 		abt->append_dim(3, "dim2");
diff --git a/unit-tests/testFile.cc b/unit-tests/testFile.cc
index 2f9d938..6414e22 100644
--- a/unit-tests/testFile.cc
+++ b/unit-tests/testFile.cc
@@ -16,6 +16,9 @@ readTestBaseline(const string &fn)
     ifstream is;
     is.open (fn.c_str(), ios::binary );
 
+    if (!is)
+        return "Could not read baseline file";
+
     // get length of file:
     is.seekg (0, ios::end);
     length = is.tellg();
diff --git a/unit-tests/test_config.h b/unit-tests/test_config.h
index 9f03448..196e91c 100644
--- a/unit-tests/test_config.h
+++ b/unit-tests/test_config.h
@@ -1,7 +1,7 @@
 #ifndef E_test_config_h
 #define E_test_config_h
 
-#define TEST_SRC_DIR "/home/jimg/src/hyrax_1.9_release/src/libdap/unit-tests"
+#define TEST_SRC_DIR "/Users/jimg/src/opendap/hyrax_git/libdap4/unit-tests"
 
 #endif
 
diff --git a/util.cc b/util.cc
index 90a8e1b..75eb104 100644
--- a/util.cc
+++ b/util.cc
@@ -76,6 +76,10 @@
 #include "Str.h"
 #include "Array.h"
 
+#include "Int64.h"
+#include "UInt64.h"
+#include "Int8.h"
+
 #include "Error.h"
 
 #include "util.h"
@@ -86,46 +90,58 @@ using namespace std;
 
 namespace libdap {
 
-/** Given a BaseType pointer, extract the string value it contains and return
- it.
+/** @brief Does this host use big-endian byte order? */
+bool is_host_big_endian()
+{
+#ifdef COMPUTE_ENDIAN_AT_RUNTIME
+
+    dods_int16 i = 0x0100;
+    char *c = reinterpret_cast<char*>(&i);
+    return *c;
+
+#else
+
+#ifdef WORDS_BIGENDIAN
+    return true;
+#else
+    return false;
+#endif
+
+#endif
+}
+
+/** Given a BaseType pointer, extract the string value it contains
 
  @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)
+string extract_string_argument(BaseType *arg)
 {
 	assert(arg);
 
     if (arg->type() != dods_str_c)
-        throw Error(malformed_expr,
-                "The function requires a DAP string argument.");
+        throw Error(malformed_expr, "The function requires a 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 = static_cast<Str*>(arg)->value();
-
-    DBG(cerr << "s: " << s << endl);
-
-    return s;
+    return static_cast<Str*>(arg)->value();
 }
 
-template<class T> static void set_array_using_double_helper(Array * a, double *src, int src_len)
+template<class T> static void set_array_using_double_helper(Array *a, double *src, int src_len)
 {
-    T *values = new T[src_len];
-    // TODO Replace new with vector<T> (vector<T> values(src_len);)
+	assert(a);
+	assert(src);
+	assert(src_len > 0);
+
+	vector<T> values(src_len);
     for (int i = 0; i < src_len; ++i)
         values[i] = (T) src[i];
 
-#ifdef VAL2BUF
-    a->val2buf(values, true);
-#else
+    // This copie the values
     a->set_value(values, src_len);
-#endif
-
-    delete[]values;
 }
 
 /** Given an array that holds some sort of numeric data, load it with values
@@ -140,6 +156,7 @@ template<class T> static void set_array_using_double_helper(Array * a, double *s
  that this variable already holds data values and, given that, the
  serialization code will not try to read the values.
 
+ @note Support for DAP4 added.
  @param dest An Array. The values are written to this array, reusing
  its storage. Existing values are lost.
  @param src The source data.
@@ -147,14 +164,18 @@ template<class T> static void set_array_using_double_helper(Array * a, double *s
  @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)
+void set_array_using_double(Array *dest, double *src, int src_len)
 {
+	assert(dest);
+	assert(src);
+	assert(src_len > 0);
+
     // 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.");
+                "The function requires a 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'
@@ -192,6 +213,20 @@ void set_array_using_double(Array * dest, double *src, int src_len)
     case dods_float64_c:
         set_array_using_double_helper<dods_float64>(dest, src, src_len);
         break;
+
+        // DAP4 support
+    case dods_uint8_c:
+        set_array_using_double_helper<dods_byte>(dest, src, src_len);
+        break;
+    case dods_int8_c:
+        set_array_using_double_helper<dods_int8>(dest, src, src_len);
+        break;
+    case dods_uint64_c:
+        set_array_using_double_helper<dods_uint64>(dest, src, src_len);
+        break;
+    case dods_int64_c:
+        set_array_using_double_helper<dods_int64>(dest, src, src_len);
+        break;
     default:
         throw InternalErr(__FILE__, __LINE__,
                 "The argument list built by the CE parser contained an unsupported numeric type.");
@@ -203,25 +238,34 @@ void set_array_using_double(Array * dest, double *src, int src_len)
 
 template<class T> static double *extract_double_array_helper(Array * a)
 {
+    assert(a);
+
     int length = a->length();
-    // Could improve this using vector<T>. jhrg
-    T *b = new T[length];
-    a->value(b);
+
+    vector<T> b(length);
+    a->value(&b[0]);    // Extract the values of 'a' to '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[] MUST be used when you are done
- the data. */
+/**
+ * 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[] MUST be used when you are done
+ * the data.
+ *
+ * @note Support added for DAP4.
+ * @param a Extract value from this Array.
+ * @return A C++/C array of doubles.
+ */
 double *extract_double_array(Array * a)
 {
+    assert(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)
@@ -251,7 +295,102 @@ double *extract_double_array(Array * a)
     case dods_float32_c:
         return extract_double_array_helper<dods_float32>(a);
     case dods_float64_c:
+        // Should not be copying these values, just read them,
+        // but older code may depend on the return of this function
+        // being something that should be deleted, so leave this
+        // alone. jhrg 2/24/15
         return extract_double_array_helper<dods_float64>(a);
+
+    // Support for DAP4
+    case dods_uint8_c:
+        return extract_double_array_helper<dods_byte>(a);
+    case dods_int8_c:
+        return extract_double_array_helper<dods_int8>(a);
+    case dods_uint64_c:
+        return extract_double_array_helper<dods_uint64>(a);
+    case dods_int64_c:
+        return extract_double_array_helper<dods_int64>(a);
+    default:
+        throw InternalErr(__FILE__, __LINE__,
+                "The argument list built by the CE parser contained an unsupported numeric type.");
+    }
+}
+
+// This helper function assume 'dest' is the correct size. This should not
+// be called when the Array 'a' is a Float64, since the values are already
+// in a double array!
+template<class T> static void extract_double_array_helper(Array * a, vector<double> &dest)
+{
+    assert(a);
+    assert(dest.size() == (unsigned long)a->length());
+
+    int length = a->length();
+
+    vector<T> b(length);
+    a->value(&b[0]);    // Extract the values of 'a' to 'b'
+
+    for (int i = 0; i < length; ++i)
+        dest[i] = (double) b[i];
+}
+
+/**
+ * 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[] MUST be used when you are done
+ * the data.
+ *
+ * @note Support added for DAP4.
+ * @param a Extract value from this Array.
+ * @param dest Put the values in this vector. A value-result parameter.
+ * @return A C++/C array of doubles.
+ */
+void extract_double_array(Array *a, vector<double> &dest)
+{
+    assert(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.");
+
+    dest.resize(a->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 (a->var()->type()) {
+    case dods_byte_c:
+        return extract_double_array_helper<dods_byte>(a, dest);
+    case dods_uint16_c:
+        return extract_double_array_helper<dods_uint16>(a, dest);
+    case dods_int16_c:
+        return extract_double_array_helper<dods_int16>(a, dest);
+    case dods_uint32_c:
+        return extract_double_array_helper<dods_uint32>(a, dest);
+    case dods_int32_c:
+        return extract_double_array_helper<dods_int32>(a, dest);
+    case dods_float32_c:
+        return extract_double_array_helper<dods_float32>(a, dest);
+    case dods_float64_c:
+        return a->value(&dest[0]);      // no need to copy the values
+        // return extract_double_array_helper<dods_float64>(a, dest);
+
+    // Support for DAP4
+    case dods_uint8_c:
+        return extract_double_array_helper<dods_byte>(a, dest);
+    case dods_int8_c:
+        return extract_double_array_helper<dods_int8>(a, dest);
+    case dods_uint64_c:
+        return extract_double_array_helper<dods_uint64>(a, dest);
+    case dods_int64_c:
+        return extract_double_array_helper<dods_int64>(a, dest);
     default:
         throw InternalErr(__FILE__, __LINE__,
                 "The argument list built by the CE parser contained an unsupported numeric type.");
@@ -261,21 +400,24 @@ double *extract_double_array(Array * a)
 /** Given a BaseType pointer, extract the numeric value it contains and return
  it in a C++ double.
 
+ @note Support for DAP4 types added.
+
  @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)
+double extract_double_value(BaseType *arg)
 {
+	assert(arg);
+
     // Simple types are Byte, ..., Float64, String and Url.
-    if (!arg->is_simple_type() || arg->type() == dods_str_c || arg->type()
-            == dods_url_c)
+    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.");
+                "The function requires a 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 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.
@@ -296,9 +438,20 @@ double extract_double_value(BaseType * arg)
         return (double)(static_cast<Float32*>(arg)->value());
     case dods_float64_c:
         return static_cast<Float64*>(arg)->value();
+
+    // Support for DAP4 types.
+    case dods_uint8_c:
+    	return (double)(static_cast<Byte*>(arg)->value());
+    case dods_int8_c:
+    	return (double)(static_cast<Int8*>(arg)->value());
+    case dods_uint64_c:
+    	return (double)(static_cast<UInt64*>(arg)->value());
+    case dods_int64_c:
+    	return (double)(static_cast<Int64*>(arg)->value());
+
     default:
         throw InternalErr(__FILE__, __LINE__,
-                "The argument list built by the CE parser contained an unsupported numeric type.");
+                "The argument list built by the parser contained an unsupported numeric type.");
     }
 }
 
@@ -387,9 +540,8 @@ libdap_version()
     return PACKAGE_VERSION;
 }
 
-extern "C"
-    const char *
-    libdap_name()
+extern "C" const char *
+libdap_name()
 {
     return PACKAGE_NAME;
 }
@@ -407,9 +559,6 @@ systime()
     if (time(&TimBin) == (time_t) - 1)
         return string("time() error");
     else {
-#if 0
-        string TimStr = ctime(&TimBin);
-#endif
         char *ctime_value = ctime(&TimBin);
         if (ctime_value) {
         	string TimStr = ctime_value;
@@ -463,6 +612,9 @@ Type get_type(const char *name)
     if (strcmp(name, "Byte") == 0)
         return dods_byte_c;
 
+    if (strcmp(name, "Char") == 0)
+        return dods_char_c;
+
     if (strcmp(name, "Int8") == 0)
         return dods_int8_c;
 
@@ -496,13 +648,19 @@ Type get_type(const char *name)
     if (strcmp(name, "String") == 0)
         return dods_str_c;
 
-    if (strcmp(name, "URL") == 0)
-        return dods_url4_c;
-
-    if (strcmp(name, "Url") == 0)
+    // accept both spellings; this might be confusing since URL
+    // could be filtered through code and come out Url. Don't know...
+    // jhrg 8/15/13
+    if (strcmp(name, "Url") == 0 || strcmp(name, "URL") == 0)
         return dods_url_c;
 
-    if (strcmp(name, "Array") == 0)
+    if (strcmp(name, "Enum") == 0)
+        return dods_enum_c;
+
+    if (strcmp(name, "Opaque") == 0)
+        return dods_opaque_c;
+
+   if (strcmp(name, "Array") == 0)
         return dods_array_c;
 
     if (strcmp(name, "Structure") == 0)
@@ -517,9 +675,15 @@ Type get_type(const char *name)
     return dods_null_c;
 }
 
-/** @brief Returns the type of the class instance as a string. */
+/**
+ * @brief Returns the type of the class instance as a string.
+ * Supports all DAP2 types and not the DAP4-only types. Also
+ * returns Url (DAP2) and not "URL" (DAP4) for the URL type.
+ * @param t The type code
+ * @return The type name in a string
+ */
 string
-type_name(Type t)
+D2type_name(Type t)
 {
     switch (t) {
     case dods_null_c:
@@ -542,6 +706,7 @@ type_name(Type t)
         return string("String");
     case dods_url_c:
         return string("Url");
+
     case dods_array_c:
         return string("Array");
     case dods_structure_c:
@@ -551,26 +716,96 @@ type_name(Type t)
     case dods_grid_c:
         return string("Grid");
 
+    default:
+        throw InternalErr(__FILE__, __LINE__, "Unknown type.");
+    }
+}
+
+/**
+ * @brief Returns the type of the class instance as a string.
+ * Supports all DAP4 types and not the DAP2-only types. Also
+ * returns URL (DAP4) and not "Url" (DAP2) for the URL type.
+ * @param t The type code
+ * @return The type name in a string
+ */
+string
+D4type_name(Type t)
+{
+    switch (t) {
+    case dods_null_c:
+        return string("Null");
+    case dods_byte_c:
+        return string("Byte");
+    case dods_char_c:
+        return string("Char");
     case dods_int8_c:
         return string("Int8");
     case dods_uint8_c:
         return string("UInt8");
+    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_int64_c:
         return string("Int64");
     case dods_uint64_c:
         return string("UInt64");
-    case dods_url4_c:
+    case dods_enum_c:
+        return string("Enum");
+
+    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_opaque_c:
+    	return string("Opaque");
+
+    case dods_array_c:
+        return string("Array");
+
+    case dods_structure_c:
+        return string("Structure");
+    case dods_sequence_c:
+        return string("Sequence");
     case dods_group_c:
         return string("Group");
-    case dods_enum_c:
-        return string("Enum");
 
     default:
         throw InternalErr(__FILE__, __LINE__, "Unknown type.");
     }
 }
 
+/** Return the type name. This function provides backward compatibility
+ * for older code that predates, and has not been ported to, DAP4. It
+ * is prejudiced toward DAP4, but if no D4 type name can be found, it
+ * types D2. If neither would return a type name, and InternalErr object
+ * is thrown.
+ *
+ * @param t The DAP2/DAP4 type
+ * @return A string naming the type, suitable for humans
+ * @exception InternalErr If not such type can be found
+ */
+string
+type_name(Type t)
+{
+	try {
+		return D4type_name(t);
+	}
+	catch (...) {
+		return D2type_name(t);
+	}
+}
+
 /** @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,
@@ -582,6 +817,7 @@ is_simple_type(Type t)
     switch (t) {
 
     case dods_byte_c:
+    case dods_char_c:
 
     case dods_int8_c:
     case dods_uint8_c:
@@ -598,9 +834,8 @@ is_simple_type(Type t)
     case dods_float64_c:
     case dods_str_c:
     case dods_url_c:
-
-    case dods_url4_c:
     case dods_enum_c:
+    case dods_opaque_c:
         return true;
 
     case dods_null_c:
@@ -609,6 +844,7 @@ is_simple_type(Type t)
     case dods_sequence_c:
     case dods_grid_c:
     case dods_group_c:
+    default:
         return false;
     }
 
@@ -624,6 +860,7 @@ is_vector_type(Type t)
     switch (t) {
     case dods_null_c:
     case dods_byte_c:
+    case dods_char_c:
 
     case dods_int8_c:
     case dods_uint8_c:
@@ -642,9 +879,8 @@ is_vector_type(Type t)
 
     case dods_str_c:
     case dods_url_c:
-
-    case dods_url4_c:
     case dods_enum_c:
+    case dods_opaque_c:
         return false;
 
     case dods_array_c:
@@ -654,6 +890,7 @@ is_vector_type(Type t)
     case dods_sequence_c:
     case dods_grid_c:
     case dods_group_c:
+    default:
         return false;
     }
 
@@ -670,6 +907,7 @@ is_constructor_type(Type t)
     switch (t) {
     case dods_null_c:
     case dods_byte_c:
+    case dods_char_c:
 
     case dods_int8_c:
     case dods_uint8_c:
@@ -686,9 +924,8 @@ is_constructor_type(Type t)
     case dods_float64_c:
     case dods_str_c:
     case dods_url_c:
-
-    case dods_url4_c:
     case dods_enum_c:
+    case dods_opaque_c:
 
     case dods_array_c:
         return false;
@@ -697,6 +934,7 @@ is_constructor_type(Type t)
     case dods_sequence_c:
     case dods_grid_c:
     case dods_group_c:
+    default:
         return true;
     }
 
@@ -711,6 +949,7 @@ bool is_integer_type(Type t)
 {
     switch (t) {
         case dods_byte_c:
+        case dods_char_c:
         case dods_int8_c:
         case dods_uint8_c:
         case dods_int16_c:
diff --git a/util.h b/util.h
index 1233e28..dc1cfe7 100644
--- a/util.h
+++ b/util.h
@@ -57,9 +57,12 @@ inline bool double_eq(double lhs, double rhs, double epsilon = 1.0e-5)
     return fabs(lhs - rhs) < epsilon;
 }
 
+bool is_host_big_endian();
+
 string extract_string_argument(BaseType *arg) ;
 double extract_double_value(BaseType *arg) ;
 double *extract_double_array(Array *a) ;
+void extract_double_array(Array *a, vector<double> &dest) ;
 void set_array_using_double(Array *dest, double *src, int src_len) ;
 
 string prune_spaces(const string &);
@@ -80,6 +83,8 @@ bool is_quoted(const string &s);
 string remove_quotes(const string &s);
 
 Type get_type(const char *name);
+string D2type_name(Type t);
+string D4type_name(Type t);
 string type_name(Type t);
 bool is_simple_type(Type t);
 bool is_vector_type(Type t);
diff --git a/xdr-datatypes.h b/xdr-datatypes.h
index c918cf8..9167595 100644
--- a/xdr-datatypes.h
+++ b/xdr-datatypes.h
@@ -20,10 +20,10 @@
 
 
 #define XDR_INT32 xdr_int32_t
-#define XDR_UINT32 xdr_uint32_t
+#define XDR_UINT32 xdr_u_int32_t
 
 #define XDR_INT16 xdr_int16_t
-#define XDR_UINT16 xdr_uint16_t
+#define XDR_UINT16 xdr_u_int16_t
 
 #define XDR_FLOAT64 xdr_double
 #define XDR_FLOAT32 xdr_float

-- 
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